Leetcode-100 二分查找常见操作总结

发布于:2025-04-04 ⋅ 阅读:(23) ⋅ 点赞:(0)

二分查找常见操作总结

1. 基本二分查找

目标: 在有序数组 nums 中查找 target 的索引(如果存在)。

适用场景:

  • 需要在 有序数组 中查找某个特定元素。
  • 适用于无重复元素的情况。

示例:
输入 nums = [1, 2, 3, 4, 5], target = 3,输出 2

def binary_search(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1  # 没找到

2. 查找左边界(Lower Bound)

目标: 找到 第一个 大于等于 target 的元素索引。

适用场景:

  • 用于查找 某个值的最左侧出现位置,如查找元素插入的位置。
  • 有重复元素 时,找到 target 最左边的位置。

示例:
输入 nums = [1, 2, 2, 2, 3], target = 2,输出 1

def lower_bound(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return left  # 返回的是第一个大于等于 target 的索引

3. 查找右边界(Upper Bound)

目标: 找到 第一个 大于 target 的元素索引。

适用场景:

  • 需要获取比目标值大的第一个位置
  • 可用于计算某个值的出现次数。

示例:
输入 nums = [1, 2, 2, 2, 3], target = 2,输出 4

def upper_bound(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] <= target:
            left = mid + 1
        else:
            right = mid - 1
    return left  # 返回的是第一个大于 target 的索引

4 查找插入位置

目标: 找到 target 应该插入 的位置。

适用场景:

  • 需要在 有序数组 中插入一个新元素,并保持有序性。
  • 可用于 二分搜索的变体,比如寻找目标元素的最左/最右位置。

示例:
输入 nums = [1, 3, 5, 6], target = 5,输出 2

def search_insert_position(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return left  # 返回插入位置

5. 寻找旋转排序数组中的最小值

目标: 在 旋转排序数组 中找到 target

适用场景:

  • 需要在 部分有序数组(如旋转排序数组)中进行二分查找。
  • nums 在某个位置发生了 旋转,但仍然部分有序。

示例:
输入 nums = [4, 5, 6, 7, 0, 1, 2], target = 0,输出 4

    def findMin(nums: List[int]) -> int:
        left, right = 0, len(nums) - 1  # 闭区间 [0, n-1]
        while left < right:  # 只要区间不缩至一个元素
            mid = (left + right) // 2
            if nums[mid] > nums[right]:  # mid 在左半部分
                left = mid + 1  # 缩小左边界
            else:  # mid 在右半部分
                right = mid  # 缩小右边界,保持 `right` 包含在内
        return nums[left]  # 最终 `left == right`,即最小值下标

二分查找常见操作对比表

操作 目标 适用场景 返回值 示例输入 示例输出
基本二分查找 在有序数组中查找目标值的索引 数组 无重复元素,查找某个特定元素 目标值的索引,若不存在返回 -1 nums = [1,2,3,4,5], target = 3 2
查找左边界 (Lower Bound) 找到第一个大于等于 target 的元素索引 有重复元素,查找 target 最左侧的位置 target 在数组中的最左索引,若不存在返回插入位置 nums = [1,2,2,2,3], target = 2 1
查找右边界 (Upper Bound) 找到第一个大于 target 的元素索引 有重复元素,查找 target 右侧界限 返回大于 target 的第一个索引 nums = [1,2,2,2,3], target = 2 4
查找插入位置 找到 target 应插入的位置 在有序数组中插入新元素,并保持有序性 target 应插入的位置 nums = [1,3,5,6], target = 5 2
寻找旋转排序数组中的最小值 在旋转排序数组中找到最小值 旋转排序数组 数组中的最小值 nums = [4,5,6,7,0,1,2] 0