16. 最接近的三数之和(双指针+减去多余步骤)

16. 最接近的三数之和

  • 双指针+减去多余步骤
  • 测试代码
  • 测试结果

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

示例 1:

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

示例 2:

输入:nums = [0,0,0], target = 1
输出:0 
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104

双指针+减去多余步骤

当我们在遍历的时候,三数之和为,sum = nums[i]+ numsli]+ nums[k],判断sum是不是与target最近的数。
使用双指针的方法:
我们要先对数组进行排序,使得它是有序的,在使用双指针时,更好的来控制哪一个指针移动。

我们需要分类讨论:
1.如果sum = target,直接返回sum。
2.如果三数之和与target的距离比ans与target的距离更近,我们将sum赋值给ans。

if (Math.abs(sum-target)

3.如果j

减去一些多余的步骤
1.设sum = nums[i]+ numsi+1]+ nums[i+2]。此时sum > target,由于数组已排序,表示了在往后面走只会使得sum变大,离target越来越远。所以这种时候可以直接break外层循环了。不过还是要判断sum是否比ans离target更近。

2.设sum = nums[i]+ nums[n-2]+ nums[n -1]。此时sum < target,由于数组已排序,表示了nums[i]加上后面任意两个数都不超过sum,在往前面走只会使得sum变大,离target越来越远。此时不应该break,而是continue,因为nums[i],后面的数字可能存在加上nums[n-2]+ nums[n -1],sum更大的情况。在之前要判断sum是否比ans离target更近。

3.当i >0并且nums[i]= nums[i-1],那么此时nums[i]和后面数字相加的情况,在之前为nums[i-1]时候就已经算过了,直接continue外层循环。

测试代码


class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
       int n=nums.length;
       int sum=0,ans=1<<30;
        for (int i = 0; i 0&&nums[i]==nums[i-1]){
                continue;
            }

            //加的两个数字在往后走,三数之和,只会离target越来越远
            sum=nums[i]+nums[i+1]+nums[i+2];
            if (sum>target){
                if ((sum-target)

测试结果

16. 最接近的三数之和(双指针+减去多余步骤)_第1张图片{:width=400}

你可能感兴趣的:(leetcode题目,算法,数据结构,排序算法)