Leetcode中一维数组与xSum
来源:互联网 发布:utorrent mac 版本 编辑:程序博客网 时间:2024/06/11 05:12
在一维数组总求各种sum的题,大都是通过两个指针从两边走向中间完成。并且前提是数组是有序的。
题目一:Two Sum
Given an array of integers, find two numbers such that they add up to a specific target number.
思路:啥都不说,排个序,while循环两个指针从分别从两头往中间走。
class Solution {public: vector<int> twoSum(vector<int> &numbers, int target) { int i=0; int j=numbers.size()-1; vector<int> res; vector<int> copy=numbers; int first,second; sort(copy.begin(),copy.end()); //第一步,排序 while(i<j){ //第二步,从两边往中间走 int sum=copy[i]+copy[j]; if(sum==target){ first=copy[i]; second=copy[j]; break; } else if(sum<target) i++; else j--; } for(int i=0;i<numbers.size();i++){ //改变了原始顺序,得额外再搜索一遍 if(res.size()<2){ if(first==numbers[i]) res.push_back(i+1); else if(second==numbers[i]) res.push_back(i+1); } } return res; }};说明:排序的话意味着改变了原始数据,不然的话可以牺牲额外的空间替换。最后需要增加一次额外的遍历,找到相应数据对应的index。还有一中替代方案,就是用map,一方面map是排序的,另一方面,map可以讲排序后的数据和排序前的index关联起来。
题目二:3Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c=0? Find all unique triples in the array which gives the sum of zero. Note
- Element in a triplet (a, b, c) must be in non-descending order (ie. a<=b<=c)
- The solution set must not contain duplicate triplets.
class Solution {public: vector<vector<int> > threeSum(vector<int> &num) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. typedef vector<int> numbers; vector<numbers> result; sort(num.begin(), num.end()); for (int x = num.size()-1; x >=2; x--) { // Do it backwards if(x < num.size()-1 & num[x] == num[x+1]) continue; // Skip same x for (int y = 0, z = x-1; y < z;) { if(y>0 && num[y]==num[y-1]) { // Skip same y y++; continue; } if(z<x-1&&num[z]==num[z+1]) { // Skip same z z--; continue; } int s = num[x] + num[y] + num[z]; if (s > 0) z--; if (s < 0) y++; if (s == 0) { vector<int> tmpOne(3); tmpOne[0] = num[y]; tmpOne[1] = num[z]; tmpOne[2] = num[x]; result.push_back(tmpOne); y++;z--; //因为要找出所有的triplet,所有搜索到这里还不能结束 } } } return result; }};说明:代码中对x, y, z的枚举都进行了相应的重复屏蔽操作。代码总共两层循环,第一层循环是对sum可能性的枚举,第二个循环就是上面的2Sum的处理,这里也可以写成一个while循环。因为要找出所有的triplet,所以找到一个结果还得继续循环。
题目三:3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S={-1 2 1 -4}, and target=1. The sum that is closest to the target is 2. (-1+2+1=2).
思路:这道题稍微要比上面的3Sum难。但还是需要sort一下。这次不是求确切的值,而是求一个近似解。
class Solution {public: int threeSumClosest(vector<int> &num, int target) { double res; double min=1<<12; if(num.size()==0) return 0; sort(num.begin(), num.end()); for(int k=num.size()-1;k>=2;k--){ //遍历第一个可能取的值int i,j;for(i=0,j=k-1; i<j;){ //2Sum的遍历double tmp_sum=num[i]+num[j]+num[k];double delta=abs(tmp_sum-target);if(delta<min){min=delta;res=tmp_sum;}if(tmp_sum<target) i++;else j--;}} return (int)res; }};
题目四:4Sum
Given an array S of n integers, are there elements a, b, c, and d in S such that a+b+c+d=target? find all unique quadruplets in the array which gives the sum of target. Note:
- Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a<=b<=c<=d)
- The solution set must not contain duplicate quadruplets
class Solution {public: vector<vector<int> > fourSum(vector<int> &num, int target) { vector<int> res; vector<vector<int> > collects; int i,j; if(num.size()==0) return collects; sort(num.begin(), num.end()); for(int k1=num.size()-1;k1>=3;k1--){ //枚举第一个数if(k1<num.size()-1&&num[k1]==num[k1+1]) //过滤掉重复的数continue;for(int k2=k1-1;k2>=2;k2--){ //枚举第二个数if(k2<k1-1&&num[k2]==num[k2+1]) //过滤掉第二个数continue;for(i=0,j=k2-1; i<j;){if(i>0 && num[i]==num[i-1]){i++; continue;}if(j<k2-1 && num[j]==num[j+1]){j--; continue;}int tmp_sum=num[i]+num[j]+num[k1]+num[k2];if(tmp_sum==target){res.push_back(num[i]);res.push_back(num[j]);res.push_back(num[k2]);res.push_back(num[k1]); collects.push_back(res);res.clear();i++;j--;}else if(tmp_sum<target) i++;else j--;}}} return collects; }};
下面继续扩大难度,在来一道附加题。
题目五:求和为s的序列
输入一个正整数s, 打印出所有和为s的连续正整数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8.
解析:这次也同样是用两个index,i, j, 不过是另个指针往中间挪动,一个负责序列的头,一个复杂序列的尾部。
void findSequenceSum(int sum){ if(sum<3) return; int i=1; //第一个index,指向地位 int j=2; //第二个index,指向高位 int mid=(1+sum)/2; int curSum=i+j; while(i<mid){ if(curSum==sum) print(i,j); while(curSum>sum&&i<mid){curSum-=i; i++; if(curSum==sum) print(i,j); }<span style="white-space:pre"></span> j++; curSum+=j; }}
void findSequenceSum2(int sum){ if(sum<3) return; int i=1; //第一个index,指向地位 int j=2; //第二个index,指向高位 int mid=(1+sum)/2; int curSum=i+j; while(i<mid){ if(curSum==sum) print(i,j); //因为要找出所有的序列,故找到之后还得继续循环 if(curSum<=sum){ j++; curSum+=j; } else{ curSum-=i; i++; } }}注意,题目2要求找到所有符合要求的序列,故找到一个之后,还得让index继续往前探寻!
总结:(1)如果是求序列的和,用两个指针从左到右,一个负责头部start,一个负责尾部end。如果当前和<target, 则end++, 否则start++. (2)如果求几个数的和,不应定是序列,则用两个指针分别从两边往中间走。(3)总的特点是都需要排序。
- Leetcode中一维数组与xSum
- Leetcode中一维数组与应用I
- Leetcode中一维数组与应用II
- Xsum问题总结
- Leetcode全数组问题
- Leetcode之数组问题
- 【leetcode 数组】Sort Colors
- Leetcode Two Sum (数组)
- (LeetCode)旋转数组
- LeetCode Contains Duplicate 数组
- LeetCode Summary Ranges 数组
- LeetCode Missing Number 数组
- LeetCode H-Index 数组
- leetcode-选择数组查找
- Leetcode数组类题目
- [leetcode] 【数组】 135. Candy
- LeetCode之反转数组
- Leetcode题解之数组
- sicily 1443.Printer Queue
- SP-0042 unknow command "$impdp"
- cf——C. Triangle(三角形的顶点)
- ssh常用用法小结
- 【Adnroid】adb remount 提示:Operation not permitted
- Leetcode中一维数组与xSum
- zookeeper 命令
- magento 模板XML文件介绍
- sql server系统表详细说明
- 如何去除UIWebView顶部的空白(IOS7)
- english websits
- 3.0及以上发现editText 光标为透明或者白色
- android 导出Jar包混淆
- 交叉编辑链的安装(本地)