16. 最接近的三数之和 java Java 中Pair的使用

Posted 可持续化发展

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了16. 最接近的三数之和 java Java 中Pair的使用相关的知识,希望对你有一定的参考价值。

Pair (JavaFX 8)

javafx.util 包中的Pair类

但是LeetCode不能用Pair类,这里只是简单提一下有这个类而已。

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

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

双指针算法

        第一层for循环是 i ,j、k为双指针。

        当 j 确定的时候,找一个最小的 k ,使得

         这样,就可以枚举出所有大于等于 target 的情况。然后看看当前和,是否最接近。如果是,就更新一下结果。

因为要找的是最接近的和,这个最接近有2层含义,大于等于 target 的最小数,或者是 小于等于 target 的最大数。

所以,如果存在

大于等于 target的最小和
小于等于 target的最大和

我们都要去检查一下,看看谁才是最接近的和。

数组的单调性。

如果不与 j 重叠,且最接近 j 的 k 满足

nums[i] + nums[j] + nums[k] >= target

并且 k - 1不与 j 重叠(k - 1 > j),则存在 k - 1 满足

nums[i] + nums[j] + nums[k - 1] < target

就要去检测一下 nums[i] + nums[j] + nums[k - 1] 这个和 ,是不是最接近的和。

 破解版

import java.util.Arrays;

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        //使用双指针算法,需要单调性,所以给数组进行排序。
        Arrays.sort(nums);
        //Pair存的是一对值(一对 value)。
        //<当前和与target的差值的绝对值,当前和>
//        Pair<Integer, Integer> res = new Pair<>(Integer.MAX_VALUE, Integer.MAX_VALUE);
        //[0]:当前和与target的差值的绝对值   [1]:最接近的和
        int[] res = new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE};
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1, k = nums.length -1; j < k; j++) {
                /**
                 * 为什么要 k - 1 > j?
                 * 因为 假设没有k - 1 > j,
                 * 如果 nums[i] + nums[j] + nums[k - 1] >= target成立,就会 k--。
                 * 这样,就可能 j 和 k 重叠。
                 * 但我们要保证 j 和 k 不重叠,所以
                 * 在进行 nums[i] + nums[j] + nums[k - 1] >= target 之前,加上 k - 1 > j,
                 * 这样,就可以提前知道,k 还能不能再往左走。如果k - 1 > j不成立,则再往左走,就和 j 重叠了,即
                 * 我们找到了 当i、j确定后,不与 j 重叠并且满足nums[i] + nums[j] + nums[k] >= target 的最小的 k
                 *
                 * 先试探 [k-1]这个位置是否满足题意一(要保证 j 和 k 不重叠),
                 * 是否满足题意二(nums[i] + nums[j] + nums[k - 1] >= target),
                 * 都满足后,再移动 k 指针(k--)
                 */
                //情况一:大于等于 target的最小和
                while (k - 1 > j && nums[i] + nums[j] + nums[k - 1] >= target)
                    k--;
                int s = nums[i] + nums[j] + nums[k];
                int dif = Math.abs(s - target);
                //如果差值更小,说明当前和更接近 target,更新 res
                //利用差值来判断接近程度
                if(dif <= res[0]){
//                    res = new Pair<>(dif, s);
                    res[0] = dif;
                    res[1] = s;
                }
                /**
                 * 当前 k 是
                 * 不与 j 重叠并且满足nums[i] + nums[j] + nums[k] >= target 的最小的 k
                 * 如果 k - 1 不与 j 重叠(k - 1 > j成立),
                 * 则存在 k - 1 ,满足
                 * nums[i] + nums[j] + nums[k - 1] < target
                 */
                //情况二:小于等于 target的最大和
                if (k - 1 > j){
                    s = nums[i] + nums[j] + nums[k - 1];
                    dif = Math.abs(s - target);
                    if(dif <= res[0]){
//                        res = new Pair<>(dif, s);
                        res[0] = dif;
                        res[1] = s;
                    }
                }
            }
        }
        return res[1];
    }
}

纯净版

import java.util.Arrays;

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int[] res = new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE};
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1, k = nums.length -1; j < k; j++) {
                while (k - 1 > j && nums[i] + nums[j] + nums[k - 1] >= target)
                    k--;
                int s = nums[i] + nums[j] + nums[k];
                int dif = Math.abs(s - target);
                if(dif <= res[0]){
                    res[0] = dif;
                    res[1] = s;
                }
                if (k - 1 > j){
                    s = nums[i] + nums[j] + nums[k - 1];
                    dif = Math.abs(s - target);
                    if(dif <= res[0]){
                        res[0] = dif;
                        res[1] = s;
                    }
                }
            }
        }
        return res[1];
    }
}

以上是关于16. 最接近的三数之和 java Java 中Pair的使用的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 16:最接近的三数之和

最接近的三数之和,完整代码实现,java及python实现。

最接近的三数之和,完整代码实现,java及python实现。

最接近的三数之和,完整代码实现,java及python实现。

力扣16-最接近的三数之和&力扣18-四数之和

LeetCode 16. 最接近的三数之和