15. 三数之和

题目描述

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

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

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

思路

  • 先排序,利用变量i遍历数组,找到nums[i]对应的nums[j],nums[k].
  • 为了方便记忆,用left代替j,right代替k.对于每一个i,都尝试找到left和right,使得nums[i] + nums[left] + nums[right] = 0.
  • 起初,left从i + 1往后找,right从n - 1往前找,当nums[i] + nums[left] + nums[right] > 0时,说明right太大了,需要right--,< 0时,说明left太小了,需要left++,=0时,说明找到了left和right,那么此时left++和right--,但是如果left++后,nums[left]的值没有改变,left需要继续++,right--后,nums[right]的值没有改变,right需要继续--,这样,三元组才不会重复。(因为已经排过序了,所以对于每一个i,其对应的let和right如果有重复的,必然是相邻的)
  • 如果i + 1后,nums[i]的值没有改变,那么直接略过,因为上一次已经找到了合适的left和right.

代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n = nums.size();
        vector<vector<int>> result;
        
        for(int i = 0;i < n;i++){
            int left = i + 1;
            int right = n - 1;

            if(i > 0 && nums[i] == nums[i - 1]) continue;
            while(left < right){
                int value = nums[left] + nums[right];

                if(nums[i] + value > 0) right--;
                else if(nums[i] + value < 0) left++;
                else{
                    result.push_back({nums[i],nums[left],nums[right]});
                    while(left < right && nums[left] == nums[left + 1]) left++;
                    while(left < right && nums[right] == nums[right - 1]) right--;
                    left++;
                    right--;
                }
            }
        }
  
        return result;
    }
};
posted @ 2024-05-28 22:07  Eaven_Wang  阅读(32)  评论(0)    收藏  举报