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;
}
};
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 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- C++中const用法总结
- CPP 虚函数、虚函数表及虚拟继承(转)
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- Deploying Control Plane Policing
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解