您的位置:首页 > 编程语言 > C语言/C++

leetcode #18 in cpp

2016-05-21 10:23 405 查看
The question is similar to 3sum. And how to solve it is thus very similar to the solution of 3sum. 

Solution: 

    we use two loops to fix 2 numbers, num[i] and num[j] where i < j. Given fixed i, j, we use two pointers, left and right, to check if the any two of the rest numbers could sum up to target - num[i] - num[j]. Be careful that we define the rest number as
the number with index > j. If we solve 3sum, we could easily solve this problem. 

    Still the trouble is to keep the duplicates away. We could see how we can avoid duplicates at line A, B, C, D. Line A, C, D are the same as the ones in 3Sum. Line B is the one which makes me debug for a while. In the beginning, I wrote line B as "if(j
> i && nums[j] == nums[j-1]) continue". This could err if we have nums[i] == nums[j]. For example, we have [2,2, 3, 4] and target is 11. The solution should be {[2,2,3,4]}. How the original line B could err is as follows: 

      When i = 0, j = 1, left = 2, right = 3, num[i] + num[j] + num[left] + num[right] = 2 + 2 + 3  +4 = 14 which is a solution. But this solution would not be checked if line B is "if(j > i && nums[j] == nums[j-1]) continue". 

To correct this, we should not skip num[j] in any cases. And we should skip num[j+1......n] if num[j+1.....n] == num[j]. This is because once num[j] has been considered, any number equal to and succeeding num[j] should be skipped.

class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if(nums.size() < 4) return res;
sort(nums.begin(), nums.end());
int left;
int right;
int cursum;
for(int i = 0; i < nums.size()-3; i ++){
if(i-1 >=0 && nums[i] == nums[i-1]) continue;//avoid duplicates -------Line A
for(int j = i + 1; j < nums.size()-2; j ++){
if(j>i+1&&nums[j] == nums[j-1]) continue;//avoid duplicates ---------Line B
left = j + 1;
right = nums.size() - 1;
while(left < right){
cursum = nums[i] + nums[j] + nums[left] + nums[right];
if(cursum == target){
res.push_back(vector<int>{nums[i], nums[j], nums[left],nums[right]});
left ++;
right --;
while(left < right && nums[left] == nums[left-1]) left++; ------Line C
while(left<right && nums[right] == nums[right + 1]) right --; ---------Line D

}else{
if(cursum>target) right --;
else left++;
}

}
}
}
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode cpp