题目:
给你一个长度为 n
的整数数组 nums
和 一个目标值 target
。请你从 nums
中选出三个整数,使它们的和与 target
最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
思路:
先将nums进行从小到大进行排序,然后采用固定一个位置i,其余两个位置进行双指针解法,一个指针lk = i+1,另一个rk = nums.length-1。当nums[lk]+nums[rk]+nums[i]<target时,使lk++;大于时,使rk--;相等时输出sum = nums[lk]+nums[rk]+nums[i]。
边界条件:
当sum1=nums[i]+nums[i+1]+nums[i+2] > target时,由于目前sum1是之后的所有可能的和的最小值,也就是说sum1-target会越来越大,就不会更加接近,这时只需要判断之前最接近的值finalSum和sum1谁更接近target,就输出谁。
代码:
public static int threeSumClosest(int[] nums, int target) {
if(nums.length==3){
return nums[0]+nums[1]+nums[2];
}
quickSort(nums, 0, nums.length-1);
int min=100000;
int sum=0;
int finalSum=0;
for(int i=0;i<nums.length-2;i++){
int sum1=nums[i]+nums[i+1]+nums[i+2];
if(sum1>=target){
if(min>(sum1-target)){
return sum1;
}else{
return finalSum;
}
}
int lk=i+1;
int rk=nums.length-1;
while(lk<rk){
sum=nums[i]+nums[lk]+nums[rk];
if(min>Math.abs(sum-target)){
finalSum=sum;
min=Math.abs(sum-target);
}
if(sum==target){
return finalSum;
}else if(sum<target){
lk++;
}else{
rk--;
}
}
}
return finalSum;
}
private static void quickSort(int[] nums, int left, int right) {
if(left>=right){
return;
}
int pivot = paration(nums, left, right);
quickSort(nums, left, pivot-1);
quickSort(nums, pivot+1, right);
}
private static int paration(int[] nums, int left, int right) {
int pivot = nums[left];
while(left<right){
while(left<right&&nums[right]>=pivot) right--;
nums[left]=nums[right];
while(left<right&&nums[left]<=pivot) left++;
nums[right]=nums[left];
}
nums[left]=pivot;
return left;
}