首页 > 其他 > 详细

leetcode 三数之和 中等

时间:2021-07-27 15:43:52      阅读:29      评论:0      收藏:0      [点我收藏+]

技术分享图片

 

 

先对整个数组进行排序,然后枚举三元组中的最小的那个数,对于剩下的数,可以用双指针处理,

假设当前枚举到的位置为 k,双指针的初始位置分别为 i = k + 1,j = nums.size() - 1.

如果 nums[k] + nums[i] + nums[j] < 0,就 ++ i。这是显然的,因为 k 位置固定不变,-- j 得到的 nums[j] 数更小,要增大三数之和,只能增大 nums[i],即 ++ i

同理,如果 nums[k] + nums[i] + nums[j] > 0,就 --j。

 

坑点1:需要注意 nums.size() 返回值类型为 size_type,是 unsigned 的,所以如果出现 nums.size() - x < 0 的情况,没有特殊处理 nums.size() - x 将会是一个极大的值

坑点2:不要枚举三数中第二大的数!(即假设 nums[k] 为中间值,然后双指针满足 i < k && k <j)。这样处理不了去重,(通过hash,set等方式去重除外)。如 [-2, -1, -1, 0, 2],需要枚举的是 index == 2 的那一位 -1,才能将 -1 作为中位数的所有满足条件的三位数找完。而 [-4, 0, 2, 2, 4],需要枚举的是 index == 2 的那一个 2,才能将 2 作为中位数的所有满足条件的三位数找完。即某些时候需要的是第一次出现的位置,某些时候需要的是最后一次出现的位置。。。而枚举最小数,就只需要处理第一次出现的位置即可。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        if(nums.size() < 3) return {};
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        for(int k = 0; k < nums.size() - 2; ++ k) {
            if(k > 0  && nums[k] == nums[k - 1]) continue;
            int i = k + 1, j = nums.size() - 1;
            while(i < j) {
                int tmp = nums[k] + nums[i] + nums[j];
                if(tmp == 0) {
                    res.push_back({nums[k], nums[i], nums[j]});
                    ++ i;
                    -- j;
                    while(i < j && nums[i] == nums[i - 1]) ++ i;
                    while(i < j && nums[j] == nums[j + 1]) -- j;
                }
                else {
                    tmp < 0 ? ++ i : -- j;
                }
            }
        }
        return res;
    }
};

 

leetcode 三数之和 中等

原文:https://www.cnblogs.com/rookie-acmer/p/15064102.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!