【LeetCode(Java) - 259】较小的三数之和

1、题目描述

在这里插入图片描述

2、解题思路

  先不考虑三个数字的问题,把问题变为:较小的两个数之和,问题就简单多了。

  首先对数组进行排序,假如数组为 nums = [3,5,2,8,1],找出和小于 7 的两个数的组合数。

  排序后为 nums=[1,2,3,5,8];target = 7。

  定义两个指针 left、right,初始时,left 指向 nums[0],right 指向最后一个元素;

  因为 nums[0] + nums[4] = 1 + 8 > 7,太大了,需要小一点,于是 right 往左走一步;

  接着 nums[0] + nums[3] = 1 + 5 = 6 < 7,符合要求,因此和小于 7 的组合数有 3 - 0 = 3 对。

  现在回到原题:求较小的三数之和的组合数。

  拿数组的一个数,比如 nums[0] 当作其中一个数,于是 target 就变为 target - nums[0],问题就转化为:从 nums[1] 到 nums[length-1] 中找到和小于 target - nums[0] 的两个数的组合数。

  双指针法的复杂度为 O(N),因为只遍历一遍数组。接着让 nums 的每一个数字都当一次“其中一个数”,嵌套后,时间复杂度就为 O(N²)

3、解题代码

class Solution {
    public int threeSumSmaller(int[] nums, int target) {
        Arrays.sort(nums);
        int sum = 0;
        for (int i = 0; i < nums.length - 2; i++) {
            sum += twoSumSmaller(nums, i + 1, target - nums[i]);
        }
        return sum;
    }

    /**
     * 从 nums[] 的 startIndex 开始的元素中找到和小于 target 的两个数的组合数
     * @param nums
     * @param startIndex
     * @param target
     * @return
     */
    private int twoSumSmaller(int[] nums, int startIndex, int target) {
        int sum = 0;
        int left = startIndex;
        int right = nums.length - 1;
        while (left < right) {
            if (nums[left] + nums[right] < target) {
                sum += right - left;
                left++;
            } else {
                right--;
            }
        }
        return sum;
    }
}
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页