返回

有序数组的巧妙加减: LeetCode 167题解剖析

见解分享

01 前言

LeetCode作为备受欢迎的算法训练平台,提供了丰富多样的题目,帮助程序员们磨炼编程技巧,提升算法能力。其中,「两数之和II - 输入有序数组」是颇具挑战的一题,需要我们运用巧妙的算法技巧才能高效地解决。

02 题目介绍

给定一个已经升序排列的有序数组nums和一个目标值target,找到两个数,使它们的和等于target。要求返回这两个数的索引,且索引值必须小于target。如果不存在这样的两个数,则返回空列表。

例如:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:nums[0] + nums[1] = 2 + 7 = 9,所以返回[0,1]

03 实现步骤

3.1 双指针法简介

双指针法是一种常用的算法技巧,通过巧妙地使用两个指针变量,可以高效地解决许多问题。在本题中,我们使用双指针法,将时间复杂度降低至O(n)。

3.2 算法步骤

  1. 初始化两个指针,left指向数组的开头,right指向数组的末尾。
  2. 比较nums[left]和nums[right]与target的和。
  3. 如果和等于target,则找到了两个数,返回它们的索引。
  4. 如果和小于target,则将left指针右移一位。
  5. 如果和大于target,则将right指针左移一位。
  6. 重复步骤2-5,直到找到两个数或left和right指针相遇。
  7. 如果left和right指针相遇,则不存在这样的两个数,返回空列表。

04 代码实现

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

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

    return []


if __name__ == "__main__":
    nums = [2, 7, 11, 15]
    target = 9
    result = two_sum(nums, target)
    print(result)  # [0, 1]

05 复杂度分析

5.1 时间复杂度

算法的时间复杂度为O(n),其中n为数组nums的长度。这是因为算法使用双指针法,每次比较两个指针指向的元素,并根据比较结果移动指针。因此,算法总共需要比较n次,时间复杂度为O(n)。

5.2 空间复杂度

算法的空间复杂度为O(1),这是因为算法只使用了两个指针变量,它们占据的空间是固定的,与数组nums的长度无关。

06 结语

本文对LeetCode 167题「两数之和II - 输入有序数组」的巧妙解法进行了详细剖析,并提供了清晰的代码实现。通过运用双指针法,我们成功地将时间复杂度降低至O(n),同时保持了O(1)的空间复杂度。无论您是编程新手还是经验丰富的开发者,都能从本文中获益匪浅,对算法问题有更深入的理解,提升问题解决能力。