三数之和
力扣 15
给你一个长度为 \(n\) 的序列,请你寻找出所有的子序列 nums[i], nums[j], nums[k]
使得 nums[i] + nums[j] + nums[k] = 0
并要求 i、j、k
两两互不相同。
输出的结果不能包含重复的子序列。
输入样例
输出样例
完善代码
排序 + 双指针
先将数组排序,然后从起点 i = 0
处一直往后面遍历,直到 i == n || nums[i] > 0
时停止;
定义左右指针 l = i + 1, r = n - 1
,这样就形成了 nums[i] <= nums[l] <= nums[r]
并且还保证了最小的 nums[i] <= 0
如果
nums[i] + nums[l] + nums[r] < 0
说明nums[l]
小了,l
要右移一个单位; 如果nums[i] + nums[l] + nums[r] > 0
说明nums[r]
大了,r
要左移一个单位; 如果nums[i] + nums[l] + nums[r] == 0
,就讲{nums[i], nums[l], nums[r]}
丢入元组set<vector<int>> st
中,这样的好处是可以对结果去重。
排序 + 双指针代码参考
class Solution {
public:
vector<vector<int>> res;
set<vector<int>> st;
vector<vector<int>> threeSum(vector<int>& nums) {
if (nums.size() < 3) return res;
int n = nums.size();
sort(nums.begin(), nums.end(), [](int a, int b)->bool{return a < b;});
for (int i = 0; i < n; i ++)
{
int l = i + 1, r = n - 1;
while (l < r)
{
int t = nums[i] + nums[l] + nums[r];
if (t == 0) st.insert({nums[i], nums[l], nums[r]}), l ++, r --;
else if (t < 0) l ++;
else r --;
}
}
for (auto x : st) res.push_back(x);
return res;
}
};