LeetCode HOT100 - 三数之和
枚举 + 双指针
首先进行排序容易想到,然后是三数,如果 \(n^3\) 显然是不行的
因此考虑怎么降低时间复杂度
考虑到两数相对是比较易做的,所以提取一个数,也就是外层遍历,固定其中一个数,进而将三数之和变成两数之和
什么情况可以使用双指针
当状态移动状态具有单调性,也就是指针移动后,肯定不会需要回到之前的状态
并且每次移动后可以排除一批不可能的状态,比如我们当前的左右端点,右端点向左移动后,无论如何左端点都不会和未移动前的右端点匹配成功
所以我们排序之后,一开始左指针在最左端,右指针在最右端
如果偏小,那么就说明左指针要右移了,如果偏大,那么就说明右指针要左移了
额外做一个相同元素跳过的逻辑避免我们得到的方案的重复
using i64 = long long;
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& a) {
sort(a.begin(), a.end());
int n = a.size();
vector<vector<int>> ans;
for (int i = 0; i < n - 2; ) {
if (a[i] > 0) break;
int l = i + 1, r = n - 1;
while (l < r) {
i64 sum = 1ll * a[i] + a[l] + a[r];
if (sum == 0) {
ans.push_back({a[i], a[l], a[r]});
l++;
r--;
while (l < r && a[l] == a[l - 1]) {
l++;
}
while (l < r && a[r] == a[r + 1]) {
r--;
}
} else if (sum < 0) {
l++;
} else {
r--;
}
}
i++;
while (i < n && a[i] == a[i - 1]) {
i++;
}
}
return ans;
}
};

浙公网安备 33010602011771号