返回

巧用有序数组高效寻和——LeetCode 算法实战

前端

导语

算法是计算机科学的基石,而 LeetCode 是算法学习的热门平台。其中,“两数之和 II - 输入有序数组”题目可谓算法入门经典。该题目要求在给定一个有序数组和一个目标和,找出数组中所有满足和为目标值的两个数对。乍一看,这似乎是一道简单的题,但如何设计高效的算法才是关键。本文将深入剖析这道题,介绍双指针和二分查找算法,带你领略算法的魅力。

双指针算法

双指针算法是一种高效的算法,用于在数组中寻找满足特定条件的元素对。它的原理是使用两个指针,一个指向数组的开头,另一个指向数组的末尾。然后,根据指针指向的元素和,移动指针,直到找到满足条件的元素对。

以“两数之和 II - 输入有序数组”为例,我们使用双指针算法如下:

def twoSum(numbers, target):
  left, right = 0, len(numbers) - 1

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

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

  return []

在这个代码中,leftright 指针分别指向数组的开头和末尾。我们通过比较 current_sumtarget,移动指针,不断缩小目标元素对的搜索范围,直到找到满足条件的元素对。

二分查找算法

二分查找算法是一种高效的搜索算法,用于在有序数组中快速查找特定元素。它的原理是将数组分成两半,不断缩小搜索范围,直到找到目标元素。

在“两数之和 II - 输入有序数组”题目中,我们可以使用二分查找算法来快速找到目标元素 target - numbers[left] 在数组中的位置。然后,我们只需判断这个位置是否在 leftright 指针之间,就能确定是否存在满足条件的元素对。

def twoSum_binary_search(numbers, target):
  left, right = 0, len(numbers) - 1

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

    if current_sum == target:
      return [left + 1, right + 1]
    elif current_sum < target:
      left += 1
    else:
      right_index = bisect.bisect_left(numbers, target - numbers[left], left + 1, right + 1)
      if right_index < right and numbers[right_index] == target - numbers[left]:
        return [left + 1, right_index + 1]
      else:
        left += 1

  return []

在这个代码中,我们使用 bisect.bisect_left 函数来进行二分查找。当 current_sum 小于 target 时,我们移动 left 指针,当 current_sum 大于 target 时,我们移动 right 指针。当 current_sum 等于 target 时,我们使用二分查找来确定是否存在满足条件的元素对。

结语

双指针和二分查找算法是计算机科学中的两大经典算法,在很多实际问题中都有着广泛的应用。通过对“两数之和 II - 输入有序数组”题目的深入分析,我们不仅掌握了这两种算法的原理和使用方法,还锻炼了我们的逻辑思维能力和编程技巧。

算法学习是一个循序渐进的过程,需要持之以恒的努力和实践。希望这篇文章能激发你的学习兴趣,让你在算法的海洋中不断探索,不断成长。