DataWhale组队学习 LeetCode task4

目录

1. 二分查找算法介绍

1.1 二分查找算法简介

1.2 二分查找算法步骤

1.3 二分查找算法思想

2. 简单二分查找

2.1 题目:704. 二分查找

2.2 解题思路

3. 二分查找细节

3.1 区间的开闭问题

3.2 mid 的取值问题

3.3 出界条件的判断

3.4 搜索区间范围的选择

4. 二分查找的两种思路

4.1 直接法

4.2 排除法

5. 总结


​​​​​​​1. 二分查找算法介绍
1.1 二分查找算法简介

二分查找算法(Binary Search Algorithm)是一种在有序数组中查找特定元素的高效搜索算法。它通过不断将查找范围减半,快速缩小目标元素的可能位置,直到找到目标元素或确定其不存在。

  • 别名:折半查找、对数查找。

  • 核心思想:通过确定目标元素所在的区间范围,反复将查找范围减半,直到找到目标元素或确定其不存在。


1.2 二分查找算法步骤

以下是二分查找的基本步骤:

  1. 初始化

    • 确定要查找的有序数组或列表,确保元素按升序或降序排列。

    • 初始化查找范围:左边界 left = 0,右边界 right = len(nums) - 1

  2. 计算中间元素

    • 计算中间位置 mid = (left + right) // 2

  3. 比较中间元素

    • 如果 nums[mid] == target,返回 mid

    • 如果 nums[mid] < target,说明目标在右半部分,更新 left = mid + 1

    • 如果 nums[mid] > target,说明目标在左半部分,更新 right = mid - 1

  4. 重复步骤 2~3

    • 直到找到目标元素或 left > right(查找范围为空),返回 -1


1.3 二分查找算法思想

二分查找的核心思想是减而治之

  • :通过条件判断,每次排除掉一定不存在目标元素的区间,缩小查找范围。

  • :在剩下的区间中继续查找目标元素。
     

2. 简单二分查找
2.1 题目:704. 二分查找
  • 描述:给定一个升序数组 nums 和一个目标值 target,返回 target 在数组中的下标,如果不存在则返回 -1

  • 示例

输入: nums = [-1, 0, 3, 5, 9, 12], target = 9
输出: 4
解释: 9 出现在 nums 中,下标为 4。
2.2 解题思路
  • 思路 1:直接法

    1. 初始化 left = 0right = len(nums) - 1

    2. 计算 mid = (left + right) // 2

    3. 比较 nums[mid] 和 target

      • 如果 nums[mid] == target,返回 mid

      • 如果 nums[mid] < target,更新 left = mid + 1

      • 如果 nums[mid] > target,更新 right = mid - 1

    4. 如果 left > right,返回 -1

  • 代码实现

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        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
  • 复杂度分析

    • 时间复杂度:O(log n)

    • 空间复杂度:O(1)


3. 二分查找细节
3.1 区间的开闭问题
  • 左闭右闭区间

    • 初始化:left = 0right = len(nums) - 1

    • 区间范围:[left, right]

    • 优点:简单直观,推荐使用。

  • 左闭右开区间

    • 初始化:left = 0right = len(nums)

    • 区间范围:[left, right)

    • 缺点:容易出错,不推荐使用。


3.2 mid 的取值问题
  • 常用公式

    1. mid = (left + right) // 2(向下取整)。

    2. mid = (left + right + 1) // 2(向上取整)。

  • 选择建议

    • 大多数情况下使用第一个公式。

    • 当区间划分为 [left, mid - 1] 和 [mid, right] 时,使用第二个公式以避免死循环。


3.3 出界条件的判断
  • left <= right

    • 出界条件:left > right

    • 优点:简单直观,推荐使用。

  • left < right

    • 出界条件:left == right

    • 需要在出界后额外判断 nums[left] 是否为目标元素。


3.4 搜索区间范围的选择
  • 常见写法

    1. left = mid + 1right = mid - 1

    2. left = mid + 1right = mid

    3. left = midright = mid - 1

  • 选择依据

    • 根据排除法的思路,优先排除目标元素一定不存在的区间。


4. 二分查找的两种思路
4.1 直接法
  • 核心思想:在循环体中直接找到目标元素并返回。

  • 适用场景:简单题目,数组中元素不重复,且目标元素性质简单。


4.2 排除法
  • 核心思想:在循环体中排除目标元素一定不存在的区间,逐步缩小查找范围。

  • 适用场景:复杂题目,如查找边界、处理重复元素等。

  • 代码实现

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        while left < right:
            mid = (left + right) // 2
            if nums[mid] < target:
                left = mid + 1
            else:
                right = mid
        return left if nums[left] == target else -1
5. 总结
  • 二分查找的核心:通过不断缩小查找范围,快速定位目标元素。

  • 关键点

    • 区间开闭问题:推荐使用左闭右闭区间。

    • mid 的取值:根据情况选择向下或向上取整。

    • 出界条件:推荐使用 left <= right

    • 搜索区间:根据排除法选择合适的区间范围。

  • 适用场景

    • 简单题目:直接法。

    • 复杂题目:排除法。

你可能感兴趣的:(学习,leetcode,算法)