题目
输入一个递增排序的数组和一个数字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]
限制:
1 <= nums.length <= 10^51 <= nums[i] <= 10^6
解析
由于题目的数组nums是递增有序的,因此本题可以采用双指针的方法。
声明left指针指向数组头部, right指针指向数组的尾部:
- 如果
nums[left] + nums[right] === target, 说明找到和为target的一对,返回[ nums[left], nums[right]]即可 - 如果
nums[left] + nums[right] > target, 说明要缩小右边界,所以right--, - 如果
nums[left] + nums[right] < target, 说明要扩大左边界,所以left++, - 当
left < right时循环执行,反之,终止循环
以 nums = [2,7,11,15], target = 9 为例, 指向步骤如下:
left = 0, right = 3, nums[left] = 2, nums[right] = 15, sum = 17, 和大于target, 所以选择 15 之前的数字,right--left = 0, right = 2, nums[left] = 2, nums[right] = 11, sum = 13, 和大于target, 所以选择 11 之前的数字,right--left = 0, right = 1, nums[left] = 2, nums[right] = 7, sum = 9, 和等于target, 找到题目要求的一对,返回[ nums[left], nums[right]]
参考代码
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let left = 0;
let right = nums.length - 1;
while(left < right) {
const sum = nums[left] + nums[right]
if ( sum === target) {
return [ nums[left], nums[right]]
} else if (sum > target ) {
right--;
} else {
left++;
}
}
};