题解 | 三数之和

三数之和

https://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711?tpId=295&tqId=731&sourceUrl=%2Fexam%2Foj%3FquestionJobId%3D10%26subTabName%3Donline_coding_page

class Solution {
  public:
    vector<vector<int>> threeSum(vector<int>& num) {
        vector<vector<int>> result;
        int n = num.size();
        if (n < 3) {
            return result;
        }

        // 先对数组进行排序
        sort(num.begin(), num.end());

        for (int i = 0; i < n - 2; i++) {
            // 跳过重复的固定数
            if (i > 0 && num[i] == num[i - 1]) {
                continue;
            }

            // 提前终止:如果当前固定的数已经大于0,由于数组已排序,后面的数都大于0
            // 三数之和不可能为0,直接结束循环
            if (num[i] > 0) {
                break;
            }

            int left = i + 1;
            int right = n - 1;
            int target = -num[i];  // 需要找到两个数之和等于 -num[i]

            while (left < right) {

                int current_sum = num[left] + num[right];

                if (current_sum == target) {
                    // 找到满足条件的三元组
                    result.push_back({num[i], num[left], num[right]});

                    // 跳过重复的左指针元素
                    while (left < right && num[left] == num[left + 1]) {
                        left++;
                    }
                    // 跳过重复的右指针元素
                    while (left < right && num[right] == num[right - 1]) {
                        right--;
                    }

                    // 移动指针寻找下一组
                    left++;
                    right--;
                } else if (current_sum < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }

        return result;
    }
};

核心思路
排序:先对数组排序,这样可以使用双指针技巧
固定一个数:遍历数组,对于每个数 num[i],在剩余部分寻找两个数使其和为 -num[i]
双指针:使用左右指针在排序后的数组中高效寻找匹配的数对
去重:在每一步都跳过重复元素,避免重复的三元组

时间复杂度
排序:O(n log n)
双指针遍历:O(n²)
总体:O(n²)

空间复杂度
结果存储:最坏情况 O(n²),但实际中远小于这个值
排序:O(log n)(快速排序的栈空间)

关键优化点
提前终止:当固定的数 num[i] > 0 时,由于数组已排序,后面的数都大于0,三数之和不可能为0
去重处理:在三个位置都进行了去重:
固定数 num[i] 的去重
左指针 num[left] 的去重
右指针 num[right] 的去重

哈希表:哈希集合和哈希映射 文章被收录于专栏

简单来说,哈希就是一个将任意长度数据&ldquo;浓缩&rdquo;成唯一固定长度&ldquo;指纹&rdquo;的单向过程。它在确保数据安全、实现高效数据结构和维护系统完整性方面,扮演着不可或缺的角色。

全部评论

相关推荐

xtu大迫杰:偶遇校友,祝校友offer打牌
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务