文章目录
Leetcode
1.问题描述
2.解决方案
解法一:排序加双指针
a.思路
b.分析总结
1.int 32位,能表示2147483647 ,大概是2*10^9 , 就是说如果题目的数有10^9,那就要注意了两个以上加起来就超过了 int 能表示范围,比如这道题,所以要记住 int 范围的事情。
解决这个问题就是把每一个nums元素强转为long long,或者也可以重建一个新的vector< long long> nums,重新赋值但是感觉有点慢,不如直接强转。并且target还是 int 不用转化
if ((long long )nums.at(first)+(long long )nums.at(second)+(long long )nums.at(left)+(long long )nums.at(right)==target)
2.这个检查重复点的处理
//重复性
//if(second!=1&&nums.at(second)==nums.at(second-1)) continue;
if(second!=first+1&&nums.at(second)==nums.at(second-1)) continue;
c.代码实现
//排序加双指针
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
int len=nums.size();
//可行性
if(len<4) return ans;
sort(nums.begin(),nums.end());
for(int first=0;first<len;first++){
//重复性
if(first!=0&&nums.at(first)==nums.at(first-1)) continue;
for(int second=first+1;second<len;second++){
//重复性
//if(second!=1&&nums.at(second)==nums.at(second-1)) continue;
if(second!=first+1&&nums.at(second)==nums.at(second-1)) continue;
int left=second+1;
int right=len-1;
while (left<right){
if ((long long )nums.at(first)+(long long )nums.at(second)+(long long )nums.at(left)+(long long )nums.at(right)==target){
vector<int> t;
t.push_back(nums.at(first));
t.push_back(nums.at(second));
t.push_back(nums.at(left));
t.push_back(nums.at(right));
ans.push_back(t);
while ((left+1)<len&&nums.at(left)==nums.at(left+1)) left++;
left++;
while ((right-1)>0&&nums.at(right)==nums.at(right-1)) right--;
right--;
continue;
}
if ((long long )nums.at(first)+(long long )nums.at(second)+(long long )nums.at(left)+(long long )nums.at(right)>target){
while ((right-1)>0&&nums.at(right)==nums.at(right-1)) right--;
right--;
continue;
}
if((long long )nums.at(first)+(long long )nums.at(second)+(long long )nums.at(left)+(long long )nums.at(right)<target){
while ((left+1)<len&&nums.at(left)==nums.at(left+1)) left++;
left++;
continue;
}
}
}
}
return ans;
}
};
解法二:排序加双指针(官方优化)
没考虑int越界问题,并且在简化判断中,会出现nums访问越界问题,先不管了,重要的是思路!
优化点一:在两个for开始之际,也就是在遍历一个序列之际,总会有些特殊情况显然不符合条件,那么我们需要找出来并且提前剔除,节省时间(这个适用于所有for开始之际,以后每个for都要往这方面考虑)!
//新加入简化判断
if (nums.at(first) + nums.at(first+1) + nums.at(first+2) + nums.at(first+3) > target) break;
if (nums.at(first) + nums.at(len - 3) + nums.at(len - 2) + nums.at(len - 1) < target) continue;
//新加入简化判断
if (nums.at(first) + nums.at(second) + nums.at(second+1) + + nums.at(second+2) > target) break;
if (nums.at(first) + nums.at(second) + nums.at(len - 2) + nums.at(len - 1) < target) continue;
优化点二:反复进行计算的提前计算,也好统一管理
//新加入提前计算
int sum = nums.at(first)+nums.at(second)+nums.at(left)+nums.at(right);
if (sum==target)
//排序加双指针(官方优化)
class Solution1 {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
int len=nums.size();
//可行性
if(len<4) return ans;
sort(nums.begin(),nums.end());
for(int first=0;first<len;first++){
//重复性
if(first!=0&&nums.at(first)==nums.at(first-1)) continue;
//新加入简化判断
if (nums.at(first) + nums.at(first+1) + nums.at(first+2) + nums.at(first+3) > target) break;
if (nums.at(first) + nums.at(len - 3) + nums.at(len - 2) + nums.at(len - 1) < target) continue;
for(int second=first+1;second<len;second++){
//重复性
//if(second!=1&&nums.at(second)==nums.at(second-1)) continue;
if(second!=first+1&&nums.at(second)==nums.at(second-1)) continue;
//新加入简化判断
if (nums.at(first) + nums.at(second) + nums.at(second+1) + + nums.at(second+2) > target) break;
if (nums.at(first) + nums.at(second) + nums.at(len - 2) + nums.at(len - 1) < target) continue;
int left=second+1;
int right=len-1;
while (left<right){
//新加入提前计算
int sum = nums.at(first)+nums.at(second)+nums.at(left)+nums.at(right);
if (sum==target){
vector<int> t;
t.push_back(nums.at(first));
t.push_back(nums.at(second));
t.push_back(nums.at(left));
t.push_back(nums.at(right));
ans.push_back(t);
while ((left+1)<len&&nums.at(left)==nums.at(left+1)) left++;
left++;
while ((right-1)>0&&nums.at(right)==nums.at(right-1)) right--;
right--;
continue;
}
if (sum>target){
while ((right-1)>0&&nums.at(right)==nums.at(right-1)) right--;
right--;
continue;
}
if(sum<target){
while ((left+1)<len&&nums.at(left)==nums.at(left+1)) left++;
left++;
continue;
}
}
}
}
return ans;
}
};