返回

走进算法的殿堂:破解二分法的奥秘-LeetCode 167

前端

算法学习从简单入手:二分法的奥秘

踏入算法学习的殿堂,我们首先要从最简单的入手,逐个突破,夯实基础。二分法就是这样一个不可或缺的基础算法,它在面试中也经常会遇到。掌握二分法,不仅能提高编程能力,还能为后续的算法学习打下坚实的基础。

一、二分法的基本原理

二分法是一种搜索算法,它通过不断地将搜索范围减半,从而快速找到目标元素。具体来说,二分法先将待搜索数组排序,然后从中间元素开始,将数组分成两半。如果目标元素大于中间元素,则在右半部分继续搜索;如果目标元素小于中间元素,则在左半部分继续搜索。如此循环往复,直到找到目标元素或者搜索范围为空。

二、二分法的应用场景

二分法在实际开发中有着广泛的应用,常见的有:

  1. 有序数组的查找:二分法是查找有序数组中最有效率的算法,时间复杂度为 O(log n)。
  2. 求解最值问题:二分法可用于求解最大值、最小值等最值问题。
  3. 判定问题:二分法可用于判定某个元素是否存在于数组中,或者满足某个条件的元素是否存在。

三、LeetCode 167:两数之和 II - 输入有序数组

为了更好地理解二分法,我们以 LeetCode 167 为例,来一步步剖析二分法的应用。

题目

给定一个包含 n 个整数的升序数组 nums 和一个目标值 target,请找出两个整数,使它们的和为 target。你可以假设该数组中不存在重复元素。

示例:

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

解题思路:

  1. 首先将 nums 数组排序(题目已给出数组是有序的)。
  2. 使用二分法查找 target - nums[i] 在数组中的位置,如果找到则返回 [nums[i], target - nums[i]]。
  3. 如果没有找到,则将 i 加 1,继续在数组中查找。
  4. 重复步骤 2 和 3,直到找到 target - nums[i] 在数组中的位置,或者 i 等于数组长度。

代码实现:

def twoSum(nums, target):
  """
  :type nums: List[int]
  :type target: int
  :rtype: List[int]
  """
  # 排序数组
  nums.sort()

  # 二分法查找 target - nums[i] 在数组中的位置
  for i in range(len(nums)):
    left = i + 1
    right = len(nums) - 1
    mid = (left + right) // 2
    while left <= right:
      if nums[mid] == target - nums[i]:
        return [nums[i], nums[mid]]
      elif nums[mid] < target - nums[i]:
        left = mid + 1
      else:
        right = mid - 1
      mid = (left + right) // 2

  # 如果没有找到,返回空列表
  return []

四、总结

二分法是一种高效且实用的算法,在实际开发中有着广泛的应用。通过本文的讲解,相信您已经对二分法有了更深入的理解。在接下来的算法学习中,您会不断遇到二分法的身影,希望您能熟练掌握并灵活运用它,不断提升自己的编程能力。