20.4.29 三数之和 中等 15


时间复杂度O(n²)

解题思路

  1. 想了10多分钟完全就没思路,只好看题解思路,懂了思路代码没什么坑,直接就写出来了;
  2. 先排序,数组的有序性方便去重;
  3. 每次固定一个数字作为第一个数,在其右边用双指针找第二第三个数。如果三个数加起来小于0,因为数组是有序的并且第一个数是固定的,那么想要得到等于0的结果只能将双指针中的左指针往右移找更大的数。同理如果三个数加起来大于0,则移动右指针。

代码思路

  1. 排除特殊情况;
  2. 排序;
  3. 第一个while明确,第一个数不能和上一次的第一个数相同,不然会出现重复结果;
  4. 获取左右指针,进入第二个while循环,结束条件是左右指针重叠;
  5. 判断时有三种情况,三数之和大于0,三数之和小于0,三数之和等于0。前两种分别移动左右指针即可。第三种,作为结果放进结果数组,并后续更新左右指针,更新时进行去重,这是就利用到了数组有序的优势,可以去重。

代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        if(nums.size()<3) return result;

        sort(nums.begin(),nums.end());

        for(int i=0; i<nums.size(); i++){
            while(i && i<nums.size() && nums[i]==nums[i-1]) i++;
            int left=i+1,right=nums.size()-1;
            while(left<right){
                if(nums[i]+nums[left]+nums[right]>0) right--;
                else if(nums[i]+nums[left]+nums[right]<0) left++;
                else if(nums[i]+nums[left]+nums[right]==0){
                    vector<int> resultIndex;
                    resultIndex.push_back(nums[i]);
                    resultIndex.push_back(nums[left]);
                    resultIndex.push_back(nums[right]);
                    result.push_back(resultIndex);
                    resultIndex.clear();
                    do{
                        left++;
                    }while(left<right && nums[left]==nums[left-1]);
                    do{
                        right--;
                    }while(left<right && nums[right]==nums[right+1]);
                }
            }
        }

        return result;
    }
};

总结

  1. 第一次完完全全的没有思路,想到的暴力也不会去重,排序去重这个真的很巧妙。

猜你喜欢

转载自www.cnblogs.com/wasi-991017/p/12800863.html
今日推荐