題目要求:
給定一個包括 n 個整數的數組 nums
和 一個目標值 target
。找出 nums
中的三個整數,使得它們的和與 target
最接近。返回這三個數的和。假定每組輸入只存在唯一答案。
例如,給定數組 nums = [-1,2,1,-4], 和 target = 1.
與 target 最接近的三個數的和爲 2. (-1 + 2 + 1 = 2).
C++代碼:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size();
sort(nums.begin(), nums.end());
int diff = INT_MAX;
int ans;
for(int i = 0; i < n-2; i++)
{
int num_i = nums[i];
int l = i+1, r = n-1;
if (i > 0 && num_i > 0 && num_i > target) return ans;
while(l < r)
{
int sum = num_i + nums[l] + nums[r];
if (diff > abs(sum - target))
{
ans = sum;
diff = abs(sum - target);
}
if (sum > target) r--;
else if (sum < target) l++;
else return sum;
}
}
return ans;
}
};
結果(8ms):
解析:
這題跟之前的第15題求三數之和基本一樣的思路
多了一個判斷當前的sum和target的差的過程而已,因爲我們要求最接近的三數之和,越接近越好
詳細解釋如下:
把nums裏的元素個數賦給n
int n = nums.size();
然後對nums的元素排序
sort(nums.begin(), nums.end());
然後初始化最大的偏差,這裏叫diff,爲INT_MAX
int diff = INT_MAX;
然後定義一個ans,就是最後返回的最接近的三數之和
int ans;
然後就是遍歷每一個元素,從左到右,已經排好序的,和第15題一樣,只遍歷到n-2
for(int i = 0; i < n-2; i++)
首先把第一個元素的值賦給num_i
int num_i = nums[i];
然後跟第15題一樣,第二個元素取第一個元素的下一位,第三個元素取最後一個元素
int l = i+1, r = n-1;
如果第一個元素都比target大了,那麼越加後面的元素,總和越大,直接返回ans即可,ans此時爲空
if (i > 0 && num_i > 0 && num_i > target) return ans;
否則,只要l<r,就執行while循環
while(l < r)
計算當前的三數之和sum
int sum = num_i + nums[l] + nums[r];
如果當前的sum和target之差的絕對值abs(sum - target),比前一次的diff小的話,那麼我們就需要更新ans和diff
ans更新爲當前的sum
diff更新爲當前的sum和target之差的絕對值abs(sum - target)
if (diff > abs(sum - target))
{
ans = sum;
diff = abs(sum - target);
}
然後我們還需要判斷我們當前的sum和target直接的關係,看到底是比target大還是比target小,我們好對第二個和第三個元素的位置進行更新,具體還是和第15題一樣
if (sum > target) r--;
else if (sum < target) l++;
else return sum;
最後注意,該題返回的是int類型的,也就是最接近的三數之和,不需要三個元素,因此最後return ans; 即可