1 问题描述
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
2 解决路线
利用排序和三指针解决。设置三个指针k, i, j指向数组不同的位置。
思路:
a.将nums数组由小到大排序。
b.固定3个指针中最边的k指针到nums数组最左端,循环。
c.在(k,nums.length-1)两端设置i,j两个指针,向内循环i,j指针。
d.如果nums[k]+nums[i]+nums[j]==target,相差0,返回三数之和;
e.更新当前最小差值,并把当前的三数之和赋值给result.
f.如果nums[k]+nums[i]+nums[j]>target,向左移动j指针;
如果nums[k]+nums[i]+nums[j]<target,向右移动i指针。
f.在移动3个指针的同时,跳过重复元素。
g.返回result,得到结果。
3 代码实现
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int threeSumClosest(int* nums, int numsSize, int target){
int k, i, j, x = 20000, result = 0;
//排序库函数
qsort(nums, numsSize, sizeof(int), cmpfunc);
for(k = 0; k < numsSize-2; k++) {
if(k > 0 && nums[k] == nums[k-1]) {
continue;
}
for(i = k+1, j = numsSize-1; i < j;) {
if(i > k+1 && nums[i] == nums[i-1]) {
i++;
continue;
}
if(j < numsSize-1 && nums[j] == nums[j+1]) {
j--;
continue;
}
int sum = nums[k] + nums[i] + nums[j];
if(sum == target) {
return sum;
}
if(abs(sum - target) <= x) {
result = sum;
x = abs(sum - target);
}
if(sum > target) {
j--;
} else {
i++;
}
}
}
return result;
}