6.三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

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

示例1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

代码:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        //res用于存储所有和为 0 且不重复的三元组
        List<List<Integer> > res = new ArrayList<>();
        //对数组进行排序
        Arrays.sort(nums);
        //遍历数组,当前元素作为三元组的第一个元素
        for(int i = 0;i<nums.length;i++){
            //由于数组排序后是递增的,而当前元素为三元组第一个元素,若当前元素>0,则三元组后两个元素也一定大于0,和肯定大于0,故可以直接退出循环
            if(nums[i]>0)break;
            //如果当前元素和上一个元素值相同,由于上一个元素已经处理过了,为了避免重复需要跳过当前元素
            if(i>0&&nums[i] == nums[i-1])continue;
            //将i+1作为三元组的第二个元素,nums.length-1作为三元组的第三个元素
            int l = i+1,r = nums.length-1;
            //第二个元素和第三个元素加上target必须为0
            int target = -nums[i];
            //查找
            while(l<r){
                //计算当前寻找的第二个元素和第三个元素之和记为temp
                int temp = nums[l]+nums[r];
                //如果满足条件
                if(temp==target){
                    //将三元组加入res
                    res.add(Arrays.asList(nums[i],nums[l],nums[r]));
                    //同时移动两个元素,一个向右移值增大,一个向左移值减小
                    l++;
                    r--;
                    //// 跳过重复元素
                    while(l<r&&nums[l]==nums[l-1])l++;
                    while(l<r&&nums[r]==nums[r+1])r--;
                }else if(temp>target)r--;//如果当前寻找的第二个元素和第三个元素之和过大,需要让第三个元素减小,即向左移
                else l++;//否则,将第二个元素向右移
            }
        }
        //返回所有和为 0 且不重复的三元组
        return res;
    }
}
posted @ 2025-03-13 20:45  回忆、少年  阅读(20)  评论(0)    收藏  举报