leetcode-最接近的三数之和

404 阅读2分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

往常周末都是睡懒觉,今天早起去体检了。每年都是到了体检的时候,才会想起来身体才是革命的本钱吧。还好都不是什么大问题,最大的问题就是自己没有坚持锻炼。
先立个Flag,每周至少有5天,专门锻炼30分钟以上吧。先把标准定的低一点,能做到最重要,不然都是5分钟热情,过了几天这个目标就抛在脑后了吧。
当然,说起坚持,一个比较好的方法是定期review,如果有1天没做到,也不要觉得反正已经没做到,破罐子破摔,后面根本就不再做的。每天坚持是每天新的挑战,能够比之前的自己坚持做更久,就是自己的突破。
每天做1题算法题,也是上个月立下的Flag,虽然已经倒了,还是希望后面能多坚持,毕竟进一寸就有进一寸的欢喜。今天继续刷leetcode第16题,跟昨天的题目非常类似,昨天要求3个数之和=0,今天要求是跟target偏离最小。

题目

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

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

思路

跟昨天的题目是非常类似的,首先肯定还是排序。 排序后,假定一个最小值a,然后从a右边的数里面找出2个b和c,使得abs(a+b+c-target)的值最小。因为a右边的数组也是有序的,这时候找b和c其实也不需要2层for循环来遍历,可以使用双指针,分别指向剩余数组的最小和最大,如果a+b+c-target小于0,就让最小值往右边走一个,如果a+b+c-target大于0,就让最大值往左边走一个。

Java版本代码

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        int len = nums.length;
        int ans = 3001;
        Arrays.sort(nums);
        for (int i = 0; i < len -2; i++) {
            if (i > 0 && nums[i] == nums[i-1]) {
                continue;
            }
            int start = i + 1;
            int end = len - 1;
            while (start < end) {
                int sum = nums[i] + nums[start] + nums[end];
                if (sum == target) {
                    ans = sum;
                    return ans;
                }
                if (Math.abs(sum - target) < Math.abs(ans - target)) {
                    ans = sum;
                }
                if (sum > target) {
                    end--;
                } else if (sum < target) {
                    start++;
                }
            }
        }
        return ans;
    }
}