三数之和 LeetCode 15题|刷题打卡

123 阅读1分钟

题目

image.png

题解

  • 先对数组排序再循环,因为排序完当循环到nums[i]>0的时候,后面的无须循环因为最左侧是正数,三个正数的和不可能是0,因为三数之和是nums[i]+nums[i+1]+nums[nums.length - 1]即nums[i]大于0 三数之和不可能为0即退出整个循环break。
  • 循环整个数组,i > 0 && nums[i - 1] == nums[i]是为了判断相同的值,发现当前值和前一个值相等直接continue。
  • 然后循环while (left < right)循环就是定义左右两个结点加上自己循环的nums[i],我们定死nums[i]让left=nums[i+1]和right=nums[nums.length - 1]两边往中间走。
  • 判断当三数之和sum==0返回,当三数之和小于0因为是有序的,肯定是左边的不够大需要left++,反之三数之和大于0就是right太大需要right--
  • 再想sum==0的时候因为题意要求不止一组满足sum==0,当sum等于0的时候需要继续往中间走继续找满足的条件,很容易想到直接让left++;和right--再往中间走的时候左右两边遇见重复的直接各自left++和right--去重。

代码

public List<List<Integer>> threeSum(int[] nums) {
    List<List<Integer>> array = new ArrayList<>();

    if (nums == null || nums.length < 3) {
        return array;
    }
    Arrays.sort(nums);
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] > 0) {
            break;
        }
        if (i > 0 && nums[i - 1] == nums[i]) {
            continue;
        }
        int left = i + 1;
        int right = nums.length - 1;
        while (left < right) {
            int temp = nums[left] + nums[right] + nums[i];
            if (temp == 0) {
                array.add(Arrays.asList(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--;
            } else if (temp < 0) {
                left++;
            } else if (temp > 0) {
                right--;

            }
        }
    }
    return array;
}

备注

本文正在参与「掘金 2021 春招闯关活动」, 点击查看