题目描述 给你一个长度为 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 解释:与 target 最接近的和是 0(0 + 0 + 0 = 0)。
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
思路 沿用上一题 三数之和 的思路,先对给定的数组进行升序排序,再利用双指针将三层循环转化为两层循环。并且只需要求出最接近的值,并不需要列出三元组,所以相对来说更简单了。
排序之后,随着下标往右移动,三数之和必然越来越大。先固定第一个数(即第一层循环),将 left 指向 i + 1,将 right 指向 length - 1,比较三个数的和 tmp 与 target 的关系。如果 tmp > target,说明 right 指针需要往左移动才能得到更接近 target 的值,反之则应将 left 指针向右移动才能得到更接近 target 的值。重复比较 tmp 与 target,直到 left == right 后变更固定的第一个数,再重复这个过程。
优化:如果 nums[left] = nums[left + 1] 或者 nums[right] = nums[right - 1] 可以跳过,提高效率。
代码实现 思路很清晰,也是提交了 4 次才过 -_-||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 import java.util.Arrays; public class Solution16 { public static int threeSumClosest (int [] nums, int target) { int length = nums.length; if (length < 3 ) { return 0 ; } Arrays.sort(nums); int closest = Integer.MAX_VALUE; int r = Integer.MAX_VALUE; for (int i = 0 ; i < length - 2 ; i++) { if (i > 0 && nums[i] == nums[i - 1 ]) { continue ; } int left = i + 1 ; int right = length - 1 ; while (left < right) { if (left > i + 1 && nums[left] == nums[left - 1 ]) { left++; continue ; } if (right < length - 1 && nums[right] == nums[right + 1 ]) { right--; continue ; } int tempTarget = nums[i] + nums[left] + nums[right]; int diff = tempTarget - target; int absDiff = Math.abs(diff); if (absDiff < closest) { closest = absDiff; r = tempTarget; } if (diff == 0 ) { return tempTarget; } else if (diff < 0 ) { left++; } else { right--; } } } return r; } public static void main (String[] args) { int [] nums = {-1000 , -5 , -5 , -5 , -5 , -5 , -5 , -1 , -1 , -1 }; System.out.println(threeSumClosest(nums, -8 )); } }