15. 三数之和

15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

 

重点:去除重复值

排序+双指针

对数组进行排序,讨论以下几种情况:

1.数组长度不足3,不可能满足条件(这里应该放到排序之前)

2.对排序后数组进行遍历,nums[i]为第一个数,如果第一个数大于0,则不可能满足最后结果为0;

如果当前数和前一个数相同,直接跳过,出去重复值;

然后看后面两个数,设l=i+1,r=n-1;对和进行判断,大于0则说明结果太大,r向左收缩;小于0则说明结果太小,l向右收缩;等于0需要继续收缩,这里要对左右的收缩去除重复值,然后再左右收缩。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        if(nums.size() < 3) return res;
        for(int i = 0;i < nums.size()-2;i++){
            if(nums[i] > 0) break;
            if(i > 0 && nums[i] == nums[i-1]) continue;//遇到重复值直接跳过
            int l = i+1,r = nums.size()-1;
            while(l < r){
                if(nums[i] + nums[l] + nums[r] > 0){
                    r--;
                }
                else if(nums[i] + nums[l] + nums[r] < 0){
                    l++;
                }
                else{
                    res.push_back({nums[i],nums[l],nums[r]});
                    while(l < r && (nums[r] == nums[r-1])) r--;//去除重复值
                    while(l < r && (nums[l] == nums[l+1])) l++;
                    r--;//双指针同时收缩
                    l++;
                }
            }
        }
        return res;
    }
};

 

 
posted @ 2023-01-13 22:41  陌初  阅读(21)  评论(0)    收藏  举报