Java做算法:三数之和

题目:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

输入:nums = [-1,0,1,2,-1,-4]
输出:[ [-1,-1,2], [-1,0,1] ]

解答此题的关键思路:用左右指针查找 nums[ i ] 的三元组,左右指针要位于 i 的右边。

详细步骤:

  1. 创建一个列表存储结果。
  2. 把数组元素从小到大排序,便于移动双指针和去重。
  3. 然后 i 遍历数组,遍历到相同的数字(已经查找过这个数的三元组)则跳出本次循环,遍历下一个数,防止找到重复的三元组。
  4. 设置while循环,查找此数的所有三元组:三个数分别为 nums[ i ], nums[ left ], nums[ right ],计算和。
  5. 如果和为 0,则添加到列表,并且同时移动左右指针,为了查找此数的其他三元组。写while循环判断如果下一个指针的元素相同,要继续移动到不同为止。
  6. 如果和小于 0 或大于 0,则分别移动左右指针

我的代码:

 public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++)
        {
            //如果最小数字大于0,则没有计算的必要了
            if(nums[i]>0) 
                break; 
            // 如果此数与上一个元素相同,则跳出本轮循环,直到元素不同为止
            if(i>0 && nums[i]==nums[i-1])
                continue; 

            int left = i+1; // left必须位于i的右边,防止重复三元组
            int right = nums.length-1;

            while(left<right)
            {
                int sum = nums[i]+nums[left]+nums[right];
                if(sum==0)
                {
                    result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    left++;
                    right--;
                   // 移动指针后,要判断移动后的元素是否与上一个相同!!并且要先判断left<right,不然会死循环。
                    while(left<right && nums[left-1]==nums[left])
                    { left++; }
                    while(left<right && nums[right+1]==nums[right])
                    { right--; }
                }
                // 如果和小于0,则移动左指针;大于0,则移动右指针。目的是让指针遍历完剩下的元素。
                else if(sum<0)
                {
                    left++;
                }
                else
                {
                    right--;
                }
            }
        }
        return result;

    }
posted @ 2025-07-22 01:52  junjunyi  阅读(44)  评论(0)    收藏  举报