注:
题目:
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] :
- 0 <= a, b, c, d < n
- a、b、c 和 d 互不相同
- nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
题解:
思路
四数之和,和15.三数之和 (opens new window)是一个思路,都是使用双指针法, 基本解法就是在15.三数之和 (opens new window)的基础上再套一层for循环。
15.三数之和 (opens new window)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下表作为双指针,找到nums[i] + nums[left] + nums[right] == 0。
四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下表作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n2),四数之和的时间复杂度是O(n3) 。
那么一样的道理,五数之和、六数之和等等都采用这种解法。
复杂度分析
时间复杂度:O(n3),其中 n 是数组的长度。排序的时间复杂度是 O(nlogn),枚举四元组的时间复杂度是 O(n3),因此总时间复杂度为O(n3)。
空间复杂度:O(logn),其中 n 是数组的长度。空间复杂度主要取决于排序额外使用的空间。此外排序修改了输入数组 nums,实际情况中不一定允许,因此也可以看成使用了一个额外的数组存储了数组 nums 的副本并排序,空间复杂度为 O(n)。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
int size=nums.size();
if(size<4){
return result;
}
for(int first=0;first<size;first++){
if(first>0&&(nums[first]==nums[first-1])){
continue;
}
for(int second=first+1;second<size;second++){
if(second>first+1&&(nums[second]==nums[second-1])){
continue;
}
//以下为双指针法寻找两数之和
int third=second+1;
int forth=size-1;
while(third<forth){
if(third>second+1&&(nums[third]==nums[third-1])){
third++;
continue;
}
if(nums[third]+nums[forth]<(target-nums[first]-nums[second])){
third++;
}
else if(nums[third]+nums[forth]>(target-nums[first]-nums[second])){
forth--;
}
else{
result.push_back({nums[first],nums[second],nums[third],nums[forth]});
third++;
forth--;
}
}
}
}
return result;
}
};