LeetCode 最接近的三个数之和

726 阅读1分钟

本题和盛水最多的容器这个题目非常的类似,我就不做过多的铺垫了,我们一起来看题目和我的解题思路吧。

最接近的三个数之和

题目

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

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

解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

提示:

3 <= nums.length <= 10^3 -10^3 <= nums[i] <= 10^3 -10^4 <= target <= 10^4

解题分析

解题思路:

如果采用暴力解题的办法时间复杂度是 O(N * N *N), 这样解题肯定是无法通过的。

对于这样的题目我们可以采用排序 + 双指针的方式来解。

  • 首先我们对于第一个数肯定是需要进行枚举的,为了更好的控制数据的大小,我们需要先对数组进行排序
  • 这样我们就可以通过将求三个数的和,转化为求两个数的和。我们可以采用双指针的方法。进行遍历。这样时间复杂度就可以降低为 O(N*N)。

解题答案

public class ThreeSumClosestTest {

    public static void main(String[] args) {
        ThreeSumClosestTest test = new ThreeSumClosestTest();
        test.threeSumClosest(new int[]{1, 2, 3, 4}, 1);
    }

    public int threeSumClosest(int[] nums, int target) {
        // 数组长度
        int len = nums.length;
        // 排序
        Arrays.sort(nums);
        int result = Integer.MAX_VALUE - target;

        for (int i = 0; i < len - 2; i++) {
            // left, right 表示两端的指针
            int left = i + 1, right = len - 1;
            // 始终保证左边的指针小于右边的指针 
            while (left < right) {
                // 三个数求和
                int sum = nums[i] + nums[left] + nums[right];
                // 情况 1,如果相等直接返回
                if (sum == target) {
                    return sum;
                // 情况 2,如果大于目标值  
                } else if (sum > target) {
                    // 判断是否比 result 更加接近 target 
                    if (Math.abs(sum - target) < Math.abs(result - target)) {
                        // 替换 target
                        result = sum;
                    }
                    // 右指针左移
                    right--;
                } else {
                    if (Math.abs(sum - target) < Math.abs(result - target)) {
                        result = sum;
                    }
                    // 左指针右移
                    left++;
                }
            }
        }
        return result;
    }
}

参考

leetcode-cn.com/problems/3s…