返回

LeetCode.167两数之和II——有序数组搜寻之道

闲谈







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

## 1. 问题

LeetCode.167两数之和II给出了一个已按照升序排列的有序数组,要求在数组中找到两个数字,使得它们的和等于一个给定的目标值。题目规定,同一个数字在数组中最多出现两次。

## 2. 算法设计

### 2.1 暴力解法

一种朴素的解法是采用暴力搜索的方法,即枚举数组中所有可能的数字对,检查它们是否满足和等于目标值。这种方法的时间复杂度为O(n^2),其中n是数组的长度。

### 2.2 双指针法

对于有序数组,我们可以利用其有序的特性,使用双指针法来解决此问题。具体做法是:

1. 将数组中的元素从前往后依次排列,并使用两个指针left和right分别指向数组的开头和末尾。
2. 计算指针指向的元素之和,如果和等于目标值,则返回这两个指针指向的元素的下标;
3. 如果和小于目标值,则将left指针向右移动一位;
4. 如果和小于目标值,则将right指针向左移动一位;
5. 重复步骤2-4,直至找到满足要求的元素对或left指针大于或等于right指针。

这种方法的时间复杂度为O(n),其中n是数组的长度。

## 3. 时间复杂度和空间复杂度分析

### 3.1 时间复杂度

* 暴力解法的时间复杂度为O(n^2),这是因为我们需要枚举所有可能的数字对,而对于每个数字对,我们需要进行一次比较操作。
* 双指针法的时间复杂度为O(n),这是因为我们只需要遍历数组一次,并且在每次比较操作后,我们都会将指针向左或向右移动一位,因此总的比较操作次数不会超过2n。

### 3.2 空间复杂度

* 暴力解法和双指针法都只需要使用常数大小的额外空间,因此它们的空间复杂度都是O(1)。

## 4. 编程实现

```python
def two_sum(numbers, target):
    """
    :type numbers: List[int]
    :type target: int
    :rtype: List[int]
    """
    left, right = 0, len(numbers) - 1

    while left < right:
        sum = numbers[left] + numbers[right]

        if sum == target:
            return [left + 1, right + 1]
        elif sum < target:
            left += 1
        else:
            right -= 1

    return []

5. 总结

本文详细分析了LeetCode.167两数之和II——输入有序数组问题,介绍了暴力解法和双指针法两种解法,并对它们的时间复杂度和空间复杂度进行了分析。此外,还提供了Python语言的代码实现。