2sum、3sum、4sum以及任意连续的数的和为sum、任意连续或者不连续的数的和为sum
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的更多相关文章
- 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)
转自 http://tech-wonderland.net/blog/summary-of-ksum-problems.html 前言: 做过leetcode的人都知道, 里面有2sum, 3sum ...
- 2Sum,3Sum,4Sum,kSum,3Sum Closest系列
1).2sum 1.题意:找出数组中和为target的所有数对 2.思路:排序数组,然后用两个指针i.j,一前一后,计算两个指针所指内容的和与target的关系,如果小于target,i右移,如果大于 ...
- LeetCode解题报告--2Sum, 3Sum, 4Sum, K Sum求和问题总结
前言: 这几天在做LeetCode 里面有2sum, 3sum(closest), 4sum等问题, 这类问题是典型的递归思路解题.该这类问题的关键在于,在进行求和求解前,要先排序Arrays.sor ...
- 秒杀 2Sum 3Sum 4Sum 算法题
2 Sum 这题是 Leetcode 的第一题,相信大部分小伙伴都听过的吧. 作为一道标着 Easy 难度的题,它真的这么简单吗? 我在之前的刷题视频里说过,大家刷题一定要吃透一类题,为什么有的人题目 ...
- 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 ...
- LeetCode Two Sum&Two Sum II - Input array is sorted&3Sum&4Sum 一锅煮题解
文章目录 Two Sum Two Sum II 3Sum 4Sum Two Sum 题意 给定一个数组,和指定一个目标和.从数组中选择两个数满足和为目标和.保证有且只有一个解.每个元素只可以用一次. ...
- 3Sum,4Sum问题
//三数和为0的问题.要求去重,并且输出数字有序.public List<List<Integer>> threeSum(int[] nums) { Arrays.sort(n ...
- lintcode 最长上升连续子序列 II(二维最长上升连续序列)
题目链接:http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/ 最长上升连续子序列 I ...
- CPU相关知识---物理CPU数、物理核数、逻辑核数、逻辑CPU数 ?
一.物理CPU数.物理核数.逻辑核数.逻辑CPU数 相互关系??? 物理CPU数 ---> 每个物理CPU对应物理核数 ---> (每个物理核数对应逻辑核数)物理CPU对应逻辑核数 --- ...
随机推荐
- 《学习OpenCV》练习题第四章第七题abc
题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事.现在开始补上. 这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环 ...
- Hadoop MapReduce概念学习系列之map并发任务数和reduce并发任务数的原理和代码实现(十八)
首先,来说的是,reduce并发任务数,默认是1. 即,在jps后,出现一个yarnchild.之后又消失. 这里,我控制reduce并发任务数6 有多少个reduce的并发任务数可以控制,但有多少个 ...
- c语言typedef的用法-解惑阿!很多天书般的东西解释的不错(转)
转自(http://www.cnblogs.com/wchhuangya/archive/2009/12/25/1632160.html) 一.基本概念剖析 int* (*a[5])(int, cha ...
- centos下apache安装后无法访问
2013.11.28遇到的问题: -------------------------------------- 一.centos下apache安装后无法访问 得查一下防火墙的问题 iptables添加 ...
- Mcafee两个Mac版本之间的区别
近期打算为Mac安装个杀毒软件,由于自己windows平台下用的是VSE,所以Mac平台也首选Mcafee家的东西了.到Mcafee官网下载点一看,有以下几个版本可以用在Mac上: 有点懵了,查看了一 ...
- Angular 中得 scope 作用域梳理
$scope 的使用贯穿整个 Angular App 应用,它与数据模型相关联,同时也是表达式执行的上下文.有了 $scope 就在视图和控制器之间建立了一个通道,基于作用域视图在修改数据时会立刻更新 ...
- oracle学习 六 删除表空间,数据文件的语句以及导入导出dmp文件的方法(持续更新中)
要想删除表空间就要先删除数据文件 例如这个例子 CREATE TABLESPACE STHSGIMGDB_SPACE11 DATAFILE 'D:\ORACLEDATABASE\JinHuaDataB ...
- 配置Synergy(Server : XP, client: Win7)
此文只是为了Mark一下配置方法,以防以后重装系统的时候,忘记. 首先,因为我的Server机器是XP,所以要求两台机器,都是安装的x86的版本,而不能是x64的版本. 我用的版本是1.4.11, ...
- Add mappings to an Elasticsearch index in realtime
Changing mapping on existing index is not an easy task. You may find the reason and possible solutio ...
- Fragment实现底部选项卡切换效果
现在很多APP的样式都是底部选项卡做为首页的,实现这样的效果,我们一般有这样几种方式,第一,最屌丝的做法,我直接自定义选项卡视图,通过监听选项卡视图,逻辑控制内容页的切换,这样做的想法一般是反正这几个 ...