2023-03-29每日一题
一、题目编号
16. 最接近的三数之和
二、题目链接
三、题目描述
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
提示:
- 3 <= nums.length <= 1000
- -1000 <= nums[i] <= 1000
- -104 <= target <= 104
四、解题代码
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size();
int res = 0;
sort(nums.begin(), nums.end());
int min0 = 100000000;
for(int i = 0; i < n; ++i){
int left = i + 1;
int right = n - 1;
while(left < right){
int temp = nums[i] + nums[left] + nums[right];
int temp1 = temp - target;
if(temp1 < 0){
++left;
} else if(temp1 == 0){
return temp;
} else{
--right;
}
if(min0 > abs(temp1)){
min0 = abs(temp1);
res = temp;
}
}
}
return res;
}
};
五、解题思路
(1) 首先先思考一个问题,如果该题目是最接近的两数之和,那么应该如何解决该问题呢。假设我们所取数字的区间是[left, right],目标值是target。
(2) 针对 (1) 中所提出的问题,我们给出双指针的解法。只要left < right,记录num 等于 nums[left] + nums[right],每次记录num与target的差值,如果差值的绝对值小于记录的差值的绝对值,那么就更新,并且记录结果为target。如果差值等于0,那么num就是我们想要的值。如果差值小于0,则表示当前值比target小,则需要left自增1,如果差值大于0,则表示当前值比target大,则表示当前值比target大,则需要right自减1。最终得到的res即为最终的res。
(3) 我们问题转换一下,我们现在是最接近的三数之和,那么我们所需要的就是确定第一个数字是多少,我们取[0,n - 3]区间的, 我们用 i 来遍历这个区间。那么我们问题成在[i + 1, n - 1]区间最接近target - nums[i]的两数之和。最终依然返回结果UI接近的三数之和的结果即可。