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;
    }
};
posted @ 2026-04-24 18:20  rdcamelot  阅读(8)  评论(0)    收藏  举报