[LeetCode] 15. 3Sum

思路:
把3Sum问题降到n个2Sum子问题, 我们能通过O(n)的时间解决2Sum问题, 所以3Sum就是O(n^2)的时间复杂度.
首先将数据排序. 然后, 进入第一层循环, 让每个元素都先尝试做首元素. 因为排好序了, 就直接考虑后面的元素就好了. 下面将剩下的元素进行2Sum寻找. 我们用的方法是首尾各拿一个指针跟踪, 如果和第一层循环中的首元素的和加起来得0, 就放到结果组中. 接下来要注意要跳过和本次循环相同的元素, 否则会有重复的结果. 还有一些细节放到注释中了.

vector<vector<int>> threeSum(vector<int>& nums) {
    vector<vector<int>> res;
    if (nums.size() < 3) return res; // 如果数据少于三个, 直接返回空数组

    sort(nums.begin(), nums.end()); // 排序数组

    for (int i = 0; i < nums.size() - 2; i++) {
        if (i && nums[i] == nums[i - 1]) continue; // 节省时间, 同样的元素只做一次首元素
        vector<int> triplet;
        int head = i + 1, tail = nums.size() - 1; // 因为排序了, 只需要考虑后面的元素
        int target = -nums[i];
        while (head < tail) {
            // 算是一种剪枝, 如果现在头两个元素已经大于目标值了, 就不用再考虑后面的情况了
            if (nums[i] + nums[head] > 0) break; 
            if (nums[head] + nums[tail] == target) {
                triplet.push_back(nums[i]);
                triplet.push_back(nums[head]);
                triplet.push_back(nums[tail]);
                res.push_back(triplet);
                triplet.clear();
                // 下面两行都是跳过后面相同的元素, 为了避免重复结果
                while (head < tail && nums[head] == nums[head + 1]) head++;
                while (head < tail && nums[tail] == nums[tail - 1]) tail--;
                head++, tail--;
            }
            else if (nums[head] + nums[tail] < target) head++;
            else tail--;
        }
    } 

    return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值