题目描述:
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
首先我们能够想到的是暴力破解,很简单,但是效率很低
class Solution {
public int threeSumClosest(int[] nums, int target) {
//首先暴力破解
int result = nums[0] + nums[1] + nums[2];
for (int i = 0; i < nums.length; i++) {
int tem1 = nums[i];
for (int j = i + 1; j < nums.length; j++) {
int tem2 = nums[j];
for (int k = j + 1; k < nums.length; k++) {
int tem3 = nums[k];
if(Math.abs(tem1 + tem2 + tem3 - target) < Math.abs(result - target)){
result = tem1 + tem2 + tem3;
}
if(result == target){
return target;
}
}
}
}
return result;
}
}
看看别人使用的双向指针,先进行排序一下,然后利用双向指针,因此效率很高,一个数字用来控制次数,一个从控制的后一个开始,一个从结尾开始,切记不要用减号来判断指针,用的是直接比较二者的大小方法,这样简单,而且不会出错,并且有一点可以优化的是当和为target时,就可以直接返回了,不需要进行接下来的判断了,因为最小的就是0,也就是target值。
class Solution {
public int threeSumClosest(int[] nums, int target) {
// 排序
Arrays.sort(nums);
int closestNum = nums[0] + nums[1] + nums[2];
for (int i = 0; i < nums.length - 2; i++) {
int l = i + 1, r = nums.length - 1;
while (l < r){
int threeSum = nums[l] + nums[r] + nums[i];
if (Math.abs(threeSum - target) < Math.abs(closestNum - target)) {
closestNum = threeSum;
}
if (threeSum > target) {
while (l < r && nums[r] == nums[r - 1]) r--;
r--;
} else if (threeSum < target) {
while (l < r && nums[l] == nums[l + 1]) l++;
l++;
} else {
// 如果已经等于target的话, 肯定是最接近的
return target;
}
}
}
return closestNum;
}}