一起养成写作习惯!这是我参与「掘金日新计划 · 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
总结
有一说一,我一开始真没搞懂怎么玩这个题目,看了题解之后也是一知半解,反复琢磨之后,才摸到一点边界,,,每次看了别人的题目,总感觉自己是个垃圾,,,