概述
题目描述
原题链接:18. 四数之和
解题思路
思路与三数之和:15. 三数之和,区别之处在于:
1、多一层for循环,用于多加一个数。
四数之和就是在三数之和多加一个数,用前两个数相加,后面两个数继续作为双指针移动判定。
2、剪枝判定条件。
(1)第一层的i,在三数之和中的条件为nums[i] > 0
,此时为target
,但不能直接用nums[i] > target
,因为可能会出现target
为和nums[i]
都为负数时,尽管nums[i]
大于target
,但可能nums[i]
后续还有负数,相加后就有可能等于target
,例如:[-2,-1,0,0]
,target=-3
,当nums[i]=-2
时,nums[i]>target
,但后续还有一个-1,可让相加后为-3。
因此,判定条件应为nums[i] > target && (target >= 0 || nums[i] >= 0)
,此时后续一定无满足相加后等于target
的条件。
(2)第二层的j,思路同上,判定条件为nums[j] + nums[i] > target && (target >= 0 || nums[j] >= 0)
。本应为nums[i] + nums[j]>=0
,但若想让该数大于等于0,那么只可能是如下两种情况:nums[i]>=0
、nums[i]<0
。可知上述三种情况下,一定都会是nums[j]>=0
时,才有nums[i] + nums[j]>=0
,故另一个判定条件为nums[j]>=0
即可。
3、去重判定条件。
(1)第一层的i,与三数之和相同,判定条件为i > 0 && nums[i] == nums[i - 1]
。
(2)第二层的j,要确保第一次j=i+1
时,没有未被记录元素被去掉,因此判定条件为j > i + 1 && nums[j] == nums[j - 1]
。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for(int i = 0; i < n - 3; i++) {
// 剪枝,避免target为负数被剪枝的情况
if(nums[i] > target && (target >= 0 || nums[i] >= 0)) break;
// 去重
if(i > 0 && nums[i] == nums[i - 1]) continue;
for(int j = i + 1; j < n - 2; j++) {
// 剪枝
if(nums[j] + nums[i] > target && (target >= 0 || nums[j] >= 0)) break;
// 去重,此时要保证j > i + 1,避免j = i + 1时,有未记录元素被去掉
if(j > i + 1 && nums[j] == nums[j - 1]) continue;
int l = j + 1, r = n - 1;
while(l < r) {
while(l < r && (long)nums[i] + nums[j] + nums[l] + nums[r] < target) l++;
while(l < r && (long)nums[i] + nums[j] + nums[l] + nums[r] > target) r--;
if(l < r && (long)nums[i] + nums[j] + nums[l] + nums[r] == target) {
res.push_back({ nums[i], nums[j], nums[l], nums[r]});
while(l < r && nums[l] == nums[l + 1]) l++;
while(l < r && nums[r] == nums[r - 1]) r--;
l++, r--;
}
}
}
}
return res;
}
};
时间复杂度
O
(
n
3
)
O(n^3)
O(n3)
空间复杂度
O
(
l
o
g
n
)
O(log n)
O(logn) (忽略存储答案的空间,额外的排序的空间复杂度为
O
(
l
o
g
n
)
O(log n)
O(logn))
参考文章:第18题. 四数之和、15. 三数之和
最后
以上就是和谐大叔为你收集整理的74、【数组】leetcode——18. 四数之和(C++版本)题目描述解题思路的全部内容,希望文章能够帮你解决74、【数组】leetcode——18. 四数之和(C++版本)题目描述解题思路所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复