15. 三数之和
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
代码
1、暴力循环
难以去重,废弃,应该没AC
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
// vector<int>::iterator it1 = nums.begin();
vector<vector<int>> res;//返回结果,数组的数组
sort(nums.begin(),nums.end());//排序(默认升序),去重用
int len = nums.size();//原序列长度
if(len < 3){
return res;
}
for(int i = 0;i < len - 2; i++){
for(int j = i + 1; j < len - 1; j++){
for(int k = j + 1; k < len; k++){
if(nums[i] + nums[j] >= 0) break;
if(nums[i] + nums[j] + nums[k] == 0){
vector<int> res1;
res1.push_back(nums[i]);
res1.push_back(nums[j]);
res1.push_back(nums[k]);
res.push_back(res1);
}
}
}
}
vector<vector<int>>::iterator it = res.begin();
for(; it != res.end(); i++){
}
return res;
}
};
2、双指针法去重
// class Solution {
// public:
// vector<vector<int>> threeSum(vector<int>& nums) {
// // vector<int>::iterator it1 = nums.begin();
// vector<vector<int>> res;//返回结果,数组的数组
// sort(nums.begin(),nums.end());//排序(默认升序),去重用
// int len = nums.size();//原序列长度
// if(len < 3){
// return res;
// }
// //定一议二
// for(int i = 0;i < len - 2; i++){
// for(int j = i + 1; j < len - 1; j++){
// for(int k = j + 1; k < len; k++){
// if(nums[i] + nums[j] >= 0) break;
// if(nums[i] + nums[j] + nums[k] == 0){
// vector<int> res1;
// res1.push_back(nums[i]);
// res1.push_back(nums[j]);
// res1.push_back(nums[k]);
// res.push_back(res1);
// }
// }
// }
// }
// vector<vector<int>>::iterator it = res.begin();
// for(; it != res.end(); i++){
// }
// return res;
// }
// };
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
// vector<int>::iterator it1 = nums.begin();
vector<vector<int>> res;//返回结果,数组的数组
sort(nums.begin(),nums.end());//排序(默认升序),去重用
int len = nums.size();//原序列长度
if(len < 3){
return res;
}
//定一(nums[i])议二(双指针法)
int l,r;
for(int i = 0;i < len; i++){
if(nums[i] > 0) break;
if(i > 0 && nums[i] == nums[i - 1]) continue; //去重
l = i + 1;
r = len - 1;
while(l < r){
int sum = nums[i] + nums[l] + nums[r];
if(sum == 0){
vector<int> res1;
res1.push_back(nums[i]);res1.push_back(nums[l]);res1.push_back(nums[r]);
res.push_back(res1);
while(l < r && nums[r] == nums[r - 1]) r--; //去重
while(l < r && nums[l] == nums[l + 1]) l++;
l++;r--;//更新指针
}
else if(sum > 0) r--;//大于0,右指针左移以获取较小值
else l++;//小于0,左指针右移以获取较大值
}
}
return res;
}
};
小结
将原数列排序,用类似二分查找的思想,用双指针来加速,遇到相邻元素相同还可以去重。