IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二分搜索模板--Python -> 正文阅读

[数据结构与算法]二分搜索模板--Python

二分法核心点

  1. 确定搜索的范围和区间
  2. 取中间的数判断是否满足条件
  3. 如果不满足条件,判定应该往哪个半边继续搜索

二分搜索根据模板,只需要修改判断条件即可

递归写法

def binary_search_recursive(nums, target, low, high):
    """
    在nums的low到high下标的闭区间中搜索target
    :param nums:
    :param target:
    :param low:
    :param high:
    :return:
    """
    if low > high:
        return -1

    middle = low + int((high - low) / 2)  # (low + high)/2会导致溢出?

    if nums[middle] == target:
        return middle

    if target < nums[middle]:
        return binary_search_recursive(nums, target, low, middle - 1)
    return binary_search_recursive(nums, target, middle + 1, high)

非递归写法

def binary_search_not_recursive(nums, target, low, high):
    while low <= high:
        middle = low + int((high - low) / 2)

        if nums[middle] == target:
            return middle

        if target < nums[middle]:
            high = middle - 1
        else:
            low = middle + 1
    return -1

题型

1.找确定的边界,如leetcode 34

def search_lower_bound(nums, target, low, high):
    if low > high:
        return -1

    middle = low + int((high - low) / 2)

    # 与模板的差异只在判断条件
    if nums[middle] == target and (middle == 0 or nums[middle - 1] < target):
        return middle

    if target <= nums[middle]:
        return search_lower_bound(nums, target, low, middle - 1)
    return search_lower_bound(nums, target, middle + 1, high)


def search_upper_bound(nums, target, low, high):
    if low > high:
        return -1

    middle = low + int((high - low) / 2)

    if nums[middle] == target and (middle == len(nums) - 1 or nums[middle + 1] > target):
        return middle

    if target <= nums[middle]:
        return search_upper_bound(nums, target, low, middle - 1)
    return search_upper_bound(nums, target, middle + 1, high)

模糊的边界

# 第一个大于target的数
def first_greater_than(nums, target, low, high):
    if low > high:
        return None

    middle = low + int((high - low) / 2)

    if nums[middle] > target and (middle == 0 or nums[middle - 1] <= target):
        return middle

    if target < nums[middle]:
        return first_greater_than(nums, target, low, middle - 1)
    return first_greater_than(nums, target, middle + 1, high)


# 最后一个小于target的数
def last_smaller_than(nums, target, low, high):
    if low > high:
        return None

    middle = low + int((high - low) / 2)

    if nums[middle] < target and (middle == len(nums) - 1 or nums[middle + 1] >= target):
        return middle

    if target < nums[middle]:
        return last_smaller_than(nums, target, low, middle - 1)
    return last_smaller_than(nums, target, middle + 1, high)

leetcode33旋转排序数组的搜索

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        low = 0
        high = len(nums) - 1
        return self.binary_search(nums, target, low, high)

    def binary_search(self, nums, target, low, high):
        if low > high:
            return -1

        middle = low + int((high - low) / 2)
        if nums[middle] == target:
            return middle

        # 与标准的binary_search相比,多了一层判断,判断哪边已经排好序
        if nums[low] <= nums[middle]:  # 左边已经排好序
            # 在左边
            if nums[low] <= target and target < nums[middle]:
                return self.binary_search(nums, target, low, middle - 1)
            # 在右边
            return self.binary_search(nums, target, middle + 1, high)
        else:  # 右边已经排好序
            # 在右边
            if nums[middle] < target and target <= nums[high]:
                return self.binary_search(nums, target, middle + 1, high)
            # 在左边
            return self.binary_search(nums, target, low, middle - 1)

不定长的边界

不知道长度的数组

# 1. 一直遍历  -- 低效
# 2. binary  low=0, high=1, high * 2 while logs[high] != null
# when logs[high] == null, 在 [high/2,high]进行二分搜索
def get_upper_bound(logs, high):
    if logs[high] is None:
        return high
    return get_upper_bound(logs, high * 2)


# 确定upper_bound后从0到upper_bound进行binary search
def binary_search(logs, low, high):
    if low > high:
        return -1

    middle = low + int((high - low) / 2)
    # 当前位置为空,而前一个不为空,说明找到边界
    if logs[middle] is None and logs[middle - 1] is not None:
        return middle

    if logs[middle] is None:
        return binary_search(logs, low, middle - 1)
    return binary_search(logs, middle + 1, high)
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:25:59  更:2021-10-26 12:27:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:46:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码