15.三数之和 leetcode-hot100

67 阅读1分钟

image.png

// 首先我们遍历数组找到数组的最大值和最小值以及 0 的个数。 如果0的个数大于或等于3,那么 三个 0 是其中的一个答案。 三个数的和为0,除了三个数都为0的答案之外,在其它答案的三个数中,至少都要有一个正数和一个负数。如果数组没有负数或正数, 那就没有其它答案了,可以直接返回。

// 根据数据的大小范围,我们可以用计数排序对整个数组进行计数,然后把负数从大到小放到数组negNums和把正数从小到大放到数组posNums中。从大到小遍历负数数组得到一个负数negNum,和从小到大遍历正数数组的到一个正数posNum,那么第三个数x的值为- negNum - posNum。当x在数组中存在(x和negNum或posNum相等的时候,在数组中至少有两个数值为x的数),那么negNum,posNum 和 x 则为其中的一个答案。





class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ret = new ArrayList<>();
        Arrays.sort(nums); //数组排序
        int n = nums.length;
       
        for (int i = 0; i < n; i++) {
         //不存在负数结束
            if (nums[i] > 0) {
                break;
            }
            //重复跳过
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int l = i + 1, r = n - 1;
            while (l < r) {
                int sum = nums[l] + nums[r] + nums[i];
                if (sum == 0) {
                    ret.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    while (r > 0 && nums[r] == nums[r - 1]) {
                        r--;
                    }
                    while (l < n - 1 && nums[l] == nums[l + 1]) {
                        l++;
                    }
                }
                //总数大于0,最大值向里面减小,反之则最小值后挪增大
                if (sum > 0) {
                    r--;
                } else {
                    l++;
                }
            }
        }
        return ret;
    }
}