leetcode 三数之和 中等

leetcode 三数之和 中等

 

 

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

假设当前枚举到的位置为 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 三数之和 中等

上一篇:VSCode 创建branch的步骤


下一篇:Dos命令 - 获取系统信息并存放到D盘下