Skip to content

167. 两数之和 II - 输入有序数组 Medium

给你一个下标从 1 开始的整数数组 numbers,该数组已按 非递减顺序排列,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1]numbers[index2] ,则 1 <= index1 < index2 <= numbers.length

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1index2

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。

示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。

示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

解题思路

输入:一个整数数组 numbers,一个目标值 target

输出:找出两个值相加等于 target,返回他们的下标

本题属于 相向双指针 问题。

我们可以用一对相向双指针去不断的找出和为 target 的组合

当和 大于 target 时移动右指针,反之移动左指针,直到找到答案位置,注意下标是从 1 开始所以要返回 [left + 1, right + 1]

代码实现

python
class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        # 初始化左右指针
        left, right = 0, len(numbers) - 1

        # 当左指针小于右指针时继续查找
        while left < right:
            # 当前两个指针指向数字的和
            s = numbers[left] + numbers[right]

            if s > target:
                # 如果和大于目标值,说明右边数字太大,右指针左移
                right -= 1
            elif s < target:
                # 如果和小于目标值,说明左边数字太小,左指针右移
                left += 1
            else:
                # 找到目标组合,返回下标(题目要求下标从1开始)
                return [left + 1, right + 1]
javascript
/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    let left = 0;
    let right = numbers.length - 1;

    while (left < right) {
        const s = numbers[left] + numbers[right];

        if (s > target) {
            right --;
        } else if (s < target) {
            left ++;
        } else {
            return [left + 1, right + 1];
        }
    }
};

复杂度分析

时间复杂度:O(n)

空间复杂度:O(1)

链接

167 国际版

167 中文版