力扣刷题------3sums问题

题目描述:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

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

示例:给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组集合为:[ [-1, 0, 1],[-1, -1, 2] ]

思路:

  • 首先对数组进行排序,排序后固定一个数 target,再使用左右指针指向 target 后面的两端,数字分别为 nums[l]  和 nums[r] ,计算三个数的和sum ,判断是否满足为 0 ,满足则添加进结果集
  • 如果 target大于 0 ,则三数之和必然无法等于 0 ,结束循环;
  • 如果 nums[i]  == nums[i−1],则说明该数字重复,会导致结果重复,所以应该跳过;
  • 当 sum  == 0  时,nums[l]  == nums[l+1]  则会导致结果重复,应该跳过,l++;
  • 当 sum == 0  时,nums[r] == nums[r-1]  则会导致结果重复,应该跳过,r-- ;
  • 当sum>0时,r--;
  • 当sum<0时,l++;
  • 时间复杂度:O(n^2),n 为数组长度

代码如下:

vector<int>> threeSum(vector<int>& nums) {
        int target;
        vector<vector<int>> ans;
        sort(nums.begin(),nums.end());   //先对数组进行排序
        for(int i=0;i<nums.size();i++){
            if(i>0&&nums[i]==nums[i-1])    //过滤重复数字
                continue;
            if((target=nums[i])>0)    //target赋值为nums[i],并判断target是否大于0,如果大于0说明都不合适
                break;
            int l=i+1,r=nums.size()-1;
            while(l<r){
                if(nums[l]+nums[r]+target<0)
                    ++l;
                else if(nums[l]+nums[r]+target>0)
                    --r;
                else{
                    ans.push_back({target,nums[l],nums[r]});  //符合条件
                    ++l,--r;
                    while(l<r&&nums[l]==nums[l-1])  //从后往前跳过重复数字
                        ++l;
                    while(l<r&&nums[r]==nums[r+1])   //从前往后跳过重复数字
                        --r;
                }
            }
        }
        return ans;
    }
};

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页