难点:如何构建循环,以及如何评价最接近?
示例1:
输入:nums=[-1,2,1,-4],target=1输出:2
解释:与target最接近的和是2(-1+2+1=2)。
示例2:
输入:nums=[000]target=1输出:0
示例3:
输入:nums=[1,110],target=-100输出:2
该问题可以采用双指针法来解决,具体思路如下:
1.对数组nums进行排序,使得其元素按升序排列;
2.固定第一个数的位置i,并使用左右指针l=i+1和r=n-1分别表示数组中的剩余待选数的范围。
3.循环内部执行以下操作:计算三个数的总和sum=nums[i]+nums[l]+nums[r],并将其与目标数target进行比较。
a.如果sum等于target,则直接返回sum;
b.如果sum小于target,则将左指针向右移动一位(即l=l+1),以尝试增加sum的值;
c.如果sum大于target,则将右指针向左移动一位(即r=r-1),以尝试减少sum的值。
4.循环结束后,返回最接近目标数target的三个数的和。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int closestSum = nums[0] + nums[1] + nums[2];
int diff = abs(closestSum - target);
for (int i = 0; i < nums.size() - 2; ++i) {
int l = i + 1;
int r = nums.size() - 1;
while (l < r) {
int sum = nums[i] + nums[l] + nums[r];
int curDiff = abs(sum - target);
if (curDiff < diff) { // 更新最接近目标数的三个数的和
diff = curDiff;
closestSum = sum;
}
if (sum == target) {
return sum; // 如果刚好等于target,则直接返回
} else if (sum < target) {
++l;
} else {
--r;
}
}
}
return closestSum;
}
int main() {
vector<int> nums = {-1, 2, 1, -4};
int target = 1;
cout << threeSumClosest(nums, target) << endl; // 输出结果
return 0;
}
这里我们定义了一个名为threeSumCloset()的函数,用于计算数组中三个数字的和,最接近给定的目标值target。在函数中,我们首先对数组进行升序排序,然后使用两个指针(l和r)指向剩余待选数字的范围,并在循环过程中通过指针的移动尝试增加或减少三个数的总和,从而逐步逼近目标数target,同时及时更新最接近目标数的三个数的和。
注意:如果题目要求找出与目标数target差距最小的三组数字之一,则需要设定一个表示当前最小差距的变量(diff),以便即时更新最接近目标数的三个数的和。该问题还可以使用暴力枚举法和哈希表等数据结构来解决,但时间复杂度通常会更高。