题目要求
和15题“三数之和”很类似,都用到了双指针。这题我套15题的思路和模板一遍就过了
整体思路
首先使用泛型算法sort对数组进行排序
接着使用第一个for循环选取first
然后利用双指针在第二个for循环中选取second和third。还是一如既往,second从小到大,而third从大到小,第二层for循环的逻辑如下:
• 当sum-target<0时,说明选的数太小了,要选大一点的数,所以往右移动second指针。
• 当sum-target>0时,说明选的数太大了,要选小一点的数,所以往左移动third指针。
• 当sum-target=0时,精准命中,直接返回sum。
• 当third=second时,退出第二层for循环。
在第二层for循环中,每算出一个新的sum,就要和当前最优情况进行比对,并且更新当前最优情况。
代码:双指针
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target)
{
//minInterval 是绝对值
int interval,minInterval = 999, sum = 0;
std::sort(nums.begin(), nums.end());
for (size_t first = 0; first < nums.size(); first++)
{
//预先定好third
int third = nums.size() - 1;
for (size_t second = first+1; second < third; ++second)
{
interval = nums[first] + nums[second] + nums[third] - target;
if (abs(interval) < minInterval)
{
minInterval = abs(interval);
sum = interval + target;
}
while (second+1 < third && interval > 0)
{
interval = nums[first] + nums[second] + nums[--third] - target;
if (abs(interval) < minInterval)
{
minInterval = abs(interval);
sum = interval + target;
}
}
//两者相遇,不可能再有新的最优值,所以break
if (second == third)
{
break;
}
}
}
return sum;
}
};
学到了什么
1、在第14题的双指针思想启发下,我在这题更进一步学会了如何使用双指针。
2、对于诸如下面的if条件判断
if (second > first + 1 && nums[second - 1] == nums[second])
一定是边界判断的逻辑表达式在前,而取值判断的逻辑表达式在后。
如果超出了数组边界,可以利用短路逻辑在第一个逻辑表达式判断时就判断为假。而如果是取值判断的逻辑表达式在前,就无法使用短路逻辑,会直接引发超出边界错误。