15. 三数之和(双指针法)(Leetcode刷题笔记)
https://lunan0320.cn
文章目录
题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题代码 C++(核心代码)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
//先排序
sort(nums.begin(),nums.end());
//nums[i] nums[left] nums[right]
for(int i = 0; i < nums.size(); i++){
//排序后,最左端大于0 直接排除
if(nums[i] > 0) return res;
//对i索引所在的值去重
/*
错误写法,这样会使得-1,-1,2的情况没有考虑进去
if(i+1<nums.size() && nums[i] == nums[i+1]) continue;
*/
if(i > 0 && nums[i] == nums[i-1]) continue;
//每一次都要重新定义left和right
int left = i + 1, right = nums.size()-1;
while(right > left){
if(nums[i] + nums[left] + nums[right] > 0){
right--;
}else if(nums[i] + nums[left] + nums[right] < 0){
left++;
}else{
//找到符合的值
res.push_back(vector<int>{nums[i],nums[left],nums[right]});
//去重,对于重复的可能组合去掉
//对于right一侧去重
while(right > left && nums[right] == nums[right-1]) right--;
//对于left一侧去重
while(right > left && nums[left] == nums[left+1]) left++;
//去重后重新赋值
right--;
left++;
}
}
}
return res;
}
};
解题代码 C++(本地编译运行)
// head.h
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
//myHashMap.h
// 15题 双指针法
#include "head.h"
class ThreeSum {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
//对于数组nums排序,从小到大
sort(nums.begin(), nums.end());
//i是左端,依次遍历
for (int i = 0; i < nums.size(); i++) {
//终止的条件是有序数组的左端都大于0
if (nums[i] > 0) return res;
//对于索引i去重
if (i > 0 && nums[i] == nums[i - 1]) continue;
//定义left和right,此处不用判断i+1是否越界,因为下面会判断left和right的关系
int left = i + 1, right = nums.size()-1;
//每一次对left和right缩小收敛
while (right > left) {
//三数之和过大 则right收敛
if (nums[i] + nums[left] + nums[right] > 0) right--;
//三数之和过小 则left收敛
else if (nums[i] + nums[left] + nums[right] < 0) left++;
else {
res.push_back(vector<int>{nums[i], nums[left], nums[right]});
//对于right侧去重
while (right > left && nums[right] == nums[right - 1]) right--;
//对于left侧去重
while (right > left && nums[left] == nums[left + 1]) left++;
//去重结束后,left和right都要更新
right--;
left++;
}
}
}
return res;
}
};
//main.cpp
#include "myHashMap.h"
int main() {
ThreeSum solution;
vector<int> nums = { -1,0,1,2,-1,-4 };
vector<vector<int>> res;
res = solution.threeSum(nums);
for (auto sub : res) {
for (auto i : sub) {
cout << i << " ";
}
cout << endl;
}
return 0;
}