Leetcode–15. 三数之和 [2020.9.10]
前言
这题其实难度并不是很大,我一开始的思路是正确的,双指针移动。但逻辑顺序没有完全搞清楚就上手编程,导致后面调bug浪费了很多时间。以后做题一定不要急于去做,一定要把整体的思路逻辑整理完毕了再下手,不然有bug修改起来很麻烦,而且思路容易紊乱。
回到该题,首先我们需要将数组元素从小到大升序排序,确定起始指针,然后在起始指针右侧元素确定左右指针。基本思想就是:如果三个元素和相加等于0.则满足要求将其放入结果数组,如果小于0,则将左指针右移;如果大于0,这右指针左移。
同时也得注意一些小细节,比如如何避免重复的元素,一开始没有整理清楚,后面编程反而会浪费许多时间。如何避免重复的关键就是当前的指针的元素与与上一次的元素不同, 即
i
>
0
,
n
u
m
s
[
i
]
!
=
n
u
m
s
[
i
−
1
]
i>0, nums[i]!=nums[i-1]
i>0,nums[i]!=nums[i−1]。如果两个指针指向同一个元素就停止。
题目
代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end()); //1. 将数据从小到大排序
vector<vector<int>> res;
int n = nums.size();
for(int i=0; i<n; i++){ // i代表着起始指针
int right=n-1, target = -nums[i]; // 右指针 right =n-1
if(i>0&&nums[i]==nums[i-1])
continue; //起始指针与后一个元素如果一样,这起始指针后移
for(int left=i+1;left<n;left++){
if(left>i+1&&nums[left]==nums[left-1])
continue; //左指针与后一个元素如果一样,这左指针右移
while(left<right&&nums[left]+nums[right]>target)
right--; //如果左右指针元素和大于0,则右指针左移
if(left==right)
break; //两个指针重复则停止
if(nums[left]+nums[right]==target)
res.push_back({nums[i],nums[left],nums[right]}); //如果结果相等,将其放入res数组
}
}
return res;
}
};
结束语
如何避免重复的关键就是当前的指针的元素与与上一次的元素不同, 即 i > 0 , n u m s [ i ] ! = n u m s [ i − 1 ] i>0, nums[i]!=nums[i-1] i>0,nums[i]!=nums[i−1]。如果两个指针指向同一个元素就停止。