LeetCode第16题:最接近的三数之和

106 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

题目描述

给你一个长度为 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

思路

最接近的三数之和这个题目,主要是将三个数传到方法里面,传入一个目标值进行过计算,如果使用暴力解法,时间复杂度会到O(n3)。首先将数组进行一个判断,如果小于3,则没有计算的意义,直接就可以返回0,在条件满足的情况下,对数组进行遍历,每一次遍历,拿到当前值,在用前指针执行当前位置的后一个数,后指针指向数组末尾的数,根据这三个数的计算结果,判断结果跟目标的距离,如果距离更近,更新结果ans,同时判断ans 跟目标值的大小关系,因为数组有序,如果 sum > target 则 end--,如果 sum < target 则 start++,如果 sum == target 则说明距离为 0 直接返回结果。

代码


           
public static int threeSumClosest(int[] nums, int target) {
  //如果数组的长度小于3,则不符合题意,没有计算的意义
  if (nums.length<3){
    return 0;
  }
  //先将数组进行排序
  Arrays.sort(nums);
  //先计算一下前面三个数,拿到结果
  int ans = nums[0] + nums[1] + nums[2];
  for(int i=0;i<nums.length;i++) {
    int start = i+1, end = nums.length - 1;
    while(start < end) {
      int sum = nums[start] + nums[end] + nums[i];
      if(Math.abs(target - sum) < Math.abs(target - ans))
        ans = sum;
      if(sum > target)
        end--;
      else if(sum < target)
        start++;
      else
        return ans;
    }
  }
  return ans;
}
public static void main(String[] args) {
  int[] nums = {-1,2,1,-4};
  System.out.println(threeSumClosest(nums,1));
  int[] nums1 = {-1,3,1,-4};
  System.out.println(threeSumClosest(nums1,2));
  int[] nums2 = {0,2,1,-4};
  System.out.println(threeSumClosest(nums2,3));
  int[] nums3 = {-1,3,1,-3};
  System.out.println(threeSumClosest(nums3,4));
}

运行结果
nums : 2
nums1 : 3
nums2 : 3
nums3 : 3

总结

有一说一,我一开始真没搞懂怎么玩这个题目,看了题解之后也是一知半解,反复琢磨之后,才摸到一点边界,,,每次看了别人的题目,总感觉自己是个垃圾,,,