原题:https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof/
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]
示例 2:
输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]
双指针法,由于已给数组有序,所有可以用类似滑动窗口的双指针法来求解
顾名思义,采用两个指针分别指向第一和最后一个数字(初始值很重要),若二者之和小于target,则左指针向右进行移动,反之,则右指针向左移动
接下来进行验证这种方法会不会丢失解:
设二者之和为total,在不考虑两指针碰撞的情况下,有以下:
【情况1】total<target:左指针向右移动
【情况1-1】total<target:说明左指针移动后依旧比target小,此时左指针左边的值对于当前右指针以及右指针左边的值而言必然不可能会被取到了,goto情况1
【情况1-2】total>target:说明左指针移动后比target大,但又由于之前比target小,所以左指针左边的值对于当前右指针的值而言必然不可能会被取到了,而右指针右边的值必然已经在之前的指针移动时考虑,所以此情况没有遗漏解,goto情况2
【情况2】total>target:右指针向左移动
【情况2-1】total<target:说明右指针移动后比target小,但又由于之前比target大,此时右指针右边的值对于当前左指针必然不可能会被取到了,而左指针左边的值也在之前的指针移动时被考虑,所以没有遗漏解,goto情况1
【情况2-2】total>target:说明右指针移动后依旧比target大,所以右指针以及右指针右边的值对于当前左指针的值而言必然不可能会被取到了,goto情况2
验证完毕
代码:
vector<int> twoSum(vector<int>& nums, int target) {
int left = 0,right = nums.size()-1;
while (left != right)
{
if (nums[left] + nums[right] > target)
right--;
else if (nums[left] + nums[right] < target)
left++;
else
return vector<int>{nums[left], nums[right]};
}
return vector<int>();
}