n^3的时间复杂度
第一层是i
第二层是j=i+1
第三层是双指针left和right从两头向里
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> quadruplets;
if(nums.size()<4){
return quadruplets;
}
// 排序
sort(nums.begin(),nums.end());
int length = nums.size();
for(int i = 0;i<length-3;i++){
// 剪枝:当前数字与前一个相同,跳过
if(i>0 && nums[i] == nums[i - 1]){
continue;
}
// 剪枝:剩下的4个数字,无论字母取都一定大于target(最小值>target)
if((long) nums[i] + nums[i+1]+nums[i+2]+nums[i+3]>target){
break;
}
// 剪枝:剩下4个数字,无论怎么取都一定小于target(最大值<target)
if((long) nums[i] + nums[length-3] + nums[length-2] + nums[length-1]<target){
continue;
}
for(int j = i+1;j<length-2;j++){
// 剪枝:当前数字与前一个相同,跳过
if(j>i+1 && nums[j] == nums[j-1]){
continue;
}
// 剪枝:剩下的4个数字,无论字母取都一定大于target(最小值>target)
if((long) nums[i]+nums[j]+nums[j+1]+nums[j+2]>target){
break;
}
// // 剪枝:剩下4个数字,无论怎么取都一定小于target(最大值<target)
if ((long) nums[i]+nums[j]+nums[length-2]+nums[length-1] < target) {
continue;
}
// 双指针
int left = j + 1, right = length - 1;
while (left < right) {
// ————4数之和————
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
//三种情况
//目标值相等,大于,小于
if (sum == target) {
//存入答案
quadruplets.push_back({nums[i], nums[j], nums[left], nums[right]});
//这里两个while循环为了把重复的左元素和右元素跳过
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
left++;
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
right--;
//sum小于target让左指针右移
} else if (sum < target) {
left++;
//sum大于target让右指针左移
} else {
right--;
}
}
}
}
return quadruplets;
}
};