【面试系列】三数之和

题意:
原题链接

思路:
两数之和的进阶版,先排序。
那么只需要固定一个左端点,对右部分执行两数之和操作,但是其中要考虑到不能有重复的组合出现。

我们考虑如下:即 n u m s [ i ] , n u m s [ j ] , n u m s [ k ] nums[i],nums[j],nums[k] nums[i],nums[j],nums[k]三个数,那么由于 n u m s [ i ] nums[i] nums[i]是不断递增的,因此如果出现相同的 n u m s [ i ] nums[i] nums[i],那么就会导致出现重复的组,对于 n u m s [ j ] nums[j] nums[j]来说是一样的。

所以对于这两者前一次遍历和当前遍历的数一致时,就直接跳过即可。

至于 n u m s [ k ] nums[k] nums[k]这个双指针中递减的数,由于 n u m s [ i ] nums[i] nums[i] n u m s [ j ] nums[j] nums[j]会跳过相同的数,因此对于相同的 n u m s [ k ] nums[k] nums[k],并没有相同的 n u m s [ i ] nums[i] nums[i] n u m s [ j ] nums[j] nums[j]与其进行搭配,所以这里的 k k k会被自动跳过。

代码:

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

Guess you like

Origin blog.csdn.net/weixin_43900869/article/details/119797291