2sum

如果数组是无序的,先排序(n*logn),然后用两个指针i,j,各自指向数组的首尾两端,令i=0,j=n-1,然后i++,j--,逐次判断a[i]+a[j]?=sum,如果某一刻a[i]+a[j]>sum,则要想办法让sum 的值减小,所以此刻i 不动,j--,如果某一刻a[i]+a[j]<sum,则要想办法让sum 的值增大,所以此刻i++,j 不动。所以,数组无序的时候,时间复杂度最终为O(n*logn+n)=O(n*logn),若原数组是有序的,则不需要事先的排序,直接O(n)搞定,且空间复杂度还是O(1),此思路是相对于上述所有思路的一种改进。

Pair findSum(int *s,int n,int x)
{
//sort(s,s+n); 如果数组非有序的,那就事先排好序O(N*logN)
int *begin=s;
int *end=s+n-;
while(begin<end) //俩头夹逼,或称两个指针两端扫描法,很经典的方法,O(N)
{
if(*begin+*end>x)
{
--end;
}
else if(*begin+*end<x)
{
++begin;
}
else
{
return Pair(*begin,*end);
} }
return Pair(-,-);
}

3sum

 vector<vector<int> > threeSum(vector<int> &num) {
if(num.empty())
return vector<vector<int> >();
sort(num.begin(),num.end());
vector<vector<int> > ret;
vector<int> tmp;
int n=num.size();
for(int i=;i<n-;i++)
{
if(i>&&num[i]==num[i-]) continue;//防止存在重复的元素
int target=-num[i];
int j=i+;
int k=n-;
while(j<k)
{
if(j<k&&k<n-&&num[k]==num[k+])
{
k--;
continue;
}
if(num[j]+num[k]==target)
{
tmp={num[i],num[j],num[k]};
ret.push_back(tmp);
j++;
k--;
}
else if(num[j]+num[k]<target)
{
j++;
}
else if(num[j]+num[k]>target)
k--;
}
}
return ret;
}

4sum

    vector<vector<int> > fourSum(vector<int> &num,int target)
{
if(num.empty())
return vector<vector<int> >();
sort(num.begin(),num.end());
vector<vector<int> > ret;
int n=num.size();
int i,j;
for(i=; i<n-; i++)
{
//只保留第一个不重复的,其余的都删了,因为left会选择重复的
if(i>=&&num[i]==num[i-])
continue;
for(j=n-; j>i+; j--)
{
//只保留最后一个不重复的,其余的都删了,因为right会选择重复的
if(j<n-&&num[j+]==num[j])
continue;
int left=i+;
int right=j-;
vector<int> tmp;
while(left<right)
{
//只保留最后一个不重复的,其余的都删了,因为left会选择重复的
if(right<j-&&num[right]==num[right+])
{
right--;
continue;
}
if(num[i]+num[j]+num[left]+num[right]==target)
{
tmp= {num[i],num[left],num[right],num[j]};
ret.push_back(tmp);
left++;
right--;
}
else if(num[i]+num[j]+num[left]+num[right]<target)
left++;
else if(num[i]+num[j]+num[left]+num[right]>target)
right--;
}
}
}
return ret;
}

任意连续数的和为sum(假设至少存在两个数)

void sum(int sum,int n)
{
if(sum<||n<)
return -;
int cursum=;
cursum=+;
int i=,j=;
while(j<=n)
{
if(cursum==sum)
{
int k=i;
while(k<=j)
{
cout<<k<<' ';
k++;
}
cout<<endl;
cursum-=i;
i++;
}
else if(cursum<sum)
{
j++;
cursum+=j;
}
else if(cursum>sum)
{
cursum-=i;
i++;
}
}
}

任意数的和为sum

用回溯的方法实现:

#include<iostream>
#include<vector>
using namespace std; void findhelper(int m,int n,int start,vector<int> &path)
{
if(m<)
return;
if(m==)
{
for(auto a:path)
cout<<a<<' ';
cout<<endl;
return;
}
for(int i=start; i<=n; ++i)
{
path.push_back(i);
findhelper(m-i,n,i+,path);
path.pop_back();
}
}
void findSum(int m,int n)
{
vector<int> path;
findhelper(m,n,,path);
} int main()
{
findSum(,);
}

用0-1背包法实现:

注意到取n,和不取n个区别即可,考虑是否取第n个数的策略,可以转化为一个只和前n-1个数相关的问题。

  • 如果取第n个数,那么问题就转化为“取前n-1个数使得它们的和为sum-n”,对应的代码语句就是sumOfkNumber(sum - n, n - 1);
  • 如果不取第n个数,那么问题就转化为“取前n-1个数使得他们的和为sum”,对应的代码语句为sumOfkNumber(sum, n - 1)。

实现代码:

#include<iostream>
#include<vector>
using namespace std; void findhelper(int sum,int n,vector<int> &path)
{
  //递归出口
if(sum<=||n<=)
return;
  //输出找到的结果
if(sum==n)
{
for(int i=path.size()-; i>=; --i)
cout<<path[i]<<' ';
cout<<n<<endl;
}
path.push_back(n); //典型的01背包问题
findhelper(sum-n,n-,path);//放第n个元素
path.pop_back();
findhelper(sum,n-,path); //不放第n个元素
}
void findSum(int m,int n)
{
vector<int> path;
findhelper(m,n,path);
} int main()
{
findSum(,);
}

存在重复元素时,求和为sum

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std; void helper(vector<int> &num,vector<int> &path,int start,int sum)
{
if(sum==)
{
for(int i=;i<path.size();++i)
cout<<path[i]<<' ';
cout<<endl;
return;
}
if(sum<)
return;
for(int i=start;i<num.size();++i)
{
if(i>start&&num[i]==num[i-])
continue;
path.push_back(num[i]);
helper(num,path,i+,sum-num[i]);
path.pop_back();
}
}
void findSum(vector<int> &num,int sum)
{
vector<int> path;
sort(num.begin(),num.end());
helper(num,path,,sum);
} int main()
{
vector<int> num={,,,,,};
findSum(num,);
}

2sum、3sum、4sum以及任意连续的数的和为sum、任意连续或者不连续的数的和为sum的更多相关文章

  1. 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)

    转自  http://tech-wonderland.net/blog/summary-of-ksum-problems.html 前言: 做过leetcode的人都知道, 里面有2sum, 3sum ...

  2. 2Sum,3Sum,4Sum,kSum,3Sum Closest系列

    1).2sum 1.题意:找出数组中和为target的所有数对 2.思路:排序数组,然后用两个指针i.j,一前一后,计算两个指针所指内容的和与target的关系,如果小于target,i右移,如果大于 ...

  3. LeetCode解题报告--2Sum, 3Sum, 4Sum, K Sum求和问题总结

    前言: 这几天在做LeetCode 里面有2sum, 3sum(closest), 4sum等问题, 这类问题是典型的递归思路解题.该这类问题的关键在于,在进行求和求解前,要先排序Arrays.sor ...

  4. 秒杀 2Sum 3Sum 4Sum 算法题

    2 Sum 这题是 Leetcode 的第一题,相信大部分小伙伴都听过的吧. 作为一道标着 Easy 难度的题,它真的这么简单吗? 我在之前的刷题视频里说过,大家刷题一定要吃透一类题,为什么有的人题目 ...

  5. 6.3Sum && 4Sum [ && K sum ] && 3Sum Closest

    3Sum Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find a ...

  6. LeetCode Two Sum&Two Sum II - Input array is sorted&3Sum&4Sum 一锅煮题解

    文章目录 Two Sum Two Sum II 3Sum 4Sum Two Sum 题意 给定一个数组,和指定一个目标和.从数组中选择两个数满足和为目标和.保证有且只有一个解.每个元素只可以用一次. ...

  7. 3Sum,4Sum问题

    //三数和为0的问题.要求去重,并且输出数字有序.public List<List<Integer>> threeSum(int[] nums) { Arrays.sort(n ...

  8. lintcode 最长上升连续子序列 II(二维最长上升连续序列)

    题目链接:http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/ 最长上升连续子序列 I ...

  9. CPU相关知识---物理CPU数、物理核数、逻辑核数、逻辑CPU数 ?

    一.物理CPU数.物理核数.逻辑核数.逻辑CPU数 相互关系??? 物理CPU数 ---> 每个物理CPU对应物理核数 ---> (每个物理核数对应逻辑核数)物理CPU对应逻辑核数 --- ...

随机推荐

  1. Java WEB —— Java提升

    Java 5.0新特性: 枚举: enum Grade{ --> 相当于类 A("80~100"),B("70~80"),C("60~70&qu ...

  2. dom 按着shift多选

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. python's descriptor II

    [python's descriptor II] For instance, a.x has a lookup chain starting with a.__dict__['x'], then ty ...

  4. ESB服务号列表

    用于以下两个网址: -浙商ESB调用规范- xml格式 -浙商ESB调用规范- json格式   ESB服务号<SERVICE_NO>{serviceNo} 接口中文意思 42000000 ...

  5. poj 2239 Selecting Courses(二分匹配简单模板)

    http://poj.org/problem?id=2239 这里要处理的是构图问题p (1 <= p <= 7), q (1 <= q <= 12)分别表示第i门课在一周的第 ...

  6. hdu 5310 Souvenir(BestCoder 1st Anniversary ($))

    http://acm.hdu.edu.cn/showproblem.php?pid=5310 题目大意:要买n个纪念品,可以单个买p元每个,可以成套买q元一套,每套有m个,求最少花费 #include ...

  7. Intellij IDEA 14.x 中的Facets和Artifacts的区别

    Facets和Artifacts的区别: Facets 表示这个module有什么特征,比如 Web,Spring和Hibernate等: Artifact 是maven中的一个概念,表示某个modu ...

  8. CCF 201403-1 相反数 (水题)

    问题描述 有 N 个非零且各不相同的整数.请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数). 输入格式 第一行包含一个正整数 N.(1 ≤ N ≤ 500). 第二行为 N 个用单 ...

  9. Spring REST实践之REST基本介绍

    REST是什么 REST(REpresentational State Transfer)是一个设计分布式web应用的框架风格,有六个基本原则: Client-Server:应用的参独立与者可分为Cl ...

  10. Unity3d:使用uWebKit插件嵌入网页,网页中的flv视频无法播放

    问题描述:unity3d程序,使用uWebKit插件嵌入网页,用来播放FLV视频,有的电脑可以正常播放,有的电脑在网页中播放不了ps:网页中的播放器用的是player.swf解决方案:是由于网页中的播 ...