给定一个长度为n的整数数组nums,找出其中的三个数,使得它们的和最接近给定的目标数target,返回这三个数的和。

难点:如何构建循环,以及如何评价最接近?
示例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),以便即时更新最接近目标数的三个数的和。该问题还可以使用暴力枚举法和哈希表等数据结构来解决,但时间复杂度通常会更高。