1.1.4 二分法的详解与扩展

二分法的详解与扩展

1)在一个有序数组中,找某个数是否存在 : 二分
2)在一个有序数组中,找>=某个数最左侧的位置
3)局部最小值问题

1)在一个有序数组中,找某个数是否存在 : 二分法原理

二分查找算法的时间复杂度为 O(log n),适用于大规模数据的快速查找。

二分查找的原理

二分查找的基本思想是通过不断地将查找范围缩小一半来定位目标值。具体步骤如下:

  1. 初始化查找范围,设定左边界 left 和右边界 right
  2. 计算中间位置 mid
  3. 比较目标值 targetarr[mid] 的大小:
    • 如果 target 等于 arr[mid],则找到了目标值,返回 True
    • 如果 target 小于 arr[mid],则目标值在左半部分,更新右边界 right = mid - 1
    • 如果 target 大于 arr[mid],则目标值在右半部分,更新左边界 left = mid + 1
  4. 重复步骤 2 和 3,直到查找范围为空(即 left > right)。如果查找范围为空且未找到目标值,则返回 False

二分查找的实现

def binary_search(arr, target):
    left, right = 0, len(arr) - 1

    while left <= right:
        mid = left + (right - left) // 2

        if arr[mid] == target:
            return True
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    return False

def exit(sortedArr, num):
    if sortedArr == None or len(sortedArr) == 0:
        return False
    L = 0
    R = len(sortedArr) - 1
    while L < R:
        mid = L + ((R - L) >> 1)
        if sortedArr[mid] == num:
            return True
        elif sortedArr[mid] > num:
            R = mid - 1
        else:
            L = mid + 1
    return sortedArr[L] == num


# 在arr上,找满足>=value的最左位置
def nearestIndex(arr, value):
    L, R = 0, len(arr)-1
    ind = -1
    while L < R:
        mid = L + ((R - L) >> 1)
        if arr[mid] >= value:
            ind = mid
            R = mid - 1
        else:
            L = mid + 1
    return ind


解释

  1. 初始化查找范围left 初始为 0,right 初始为数组长度减 1。
  2. 计算中间位置mid = left + (right - left) // 2。这种计算方法可以避免大数相加时的整数溢出问题。
  3. 比较目标值与中间值
    • 如果 arr[mid] == target,返回 True
    • 如果 arr[mid] < target,更新左边界 left = mid + 1
    • 如果 arr[mid] > target,更新右边界 right = mid - 1
  4. 重复步骤 2 和 3,直到 left > right。如果查找范围为空且未找到目标值,返回 False

时间和空间复杂度

  • 时间复杂度:O(log n),因为每次查找范围都减半。
  • 空间复杂度:O(1),因为只使用了常数级别的额外空间。

2)在一个有序数组中,找>=某个数最左侧的位置

在一个有序数组中查找大于等于某个数的最左侧位置,可以使用二分查找(Binary Search)算法的变种。
这个问题的具体要求是找到数组中第一个大于等于目标值的位置。使用二分查找可以在 O(log n) 的时间复杂度内高效完成这个任务。

二分查找变种的原理

这个问题的基本思路是使用二分查找来定位第一个大于等于目标值 target 的位置。具体步骤如下:

  1. 初始化查找范围,设定左边界 left 和右边界 right
  2. 计算中间位置 mid
  3. 比较目标值 targetarr[mid] 的大小:
    • 如果 arr[mid] 大于等于 target,则目标值在左半部分,更新右边界 right = mid - 1,并记录当前的 mid 作为候选位置。
    • 如果 arr[mid] 小于 target,则目标值在右半部分,更新左边界 left = mid + 1
  4. 重复步骤 2 和 3,直到查找范围为空(即 left > right)。最终返回记录的候选位置。

二分查找变种的实现

以下是查找大于等于某个数的最左侧位置的 Python 实现:

def find_leftmost_ge(arr, target):
    left, right = 0, len(arr) - 1
    result = -1  # 初始化结果为 -1,表示未找到

    while left <= right:
        mid = left + (right - left) // 2

        if arr[mid] >= target:
            result = mid  # 记录当前的候选位置
            right = mid - 1  # 缩小查找范围到左半部分
        else:
            left = mid + 1  # 缩小查找范围到右半部分

    return result

3) 局部最小值问题

示例

- 对于数组 `[9, 6, 3, 14, 5, 7, 4]`,元素 `6` 和 `3` 都是局部最小值。
- 对于数组 `[1, 2, 3, 4, 5]`,元素 `1` 是局部最小值。
- 对于数组 `[5, 4, 3, 2, 1]`,元素 `1` 是局部最小值。

算法思路

采用二分查找的思路,可以在 O(log n) 的时间复杂度内找到一个局部最小值。具体步骤如下:

  1. 如果数组长度为 1,则直接返回该元素。
  2. 如果数组长度大于 1,检查数组的边界元素:
    • 如果第一个元素小于或等于第二个元素,则第一个元素为局部最小值。
    • 如果最后一个元素小于或等于倒数第二个元素,则最后一个元素为局部最小值。
  3. 如果上述条件都不满足,进行二分查找:
    • 计算中间位置 mid
    • 如果 arr[mid] 小于或等于 arr[mid - 1]arr[mid + 1],则 arr[mid] 为局部最小值。
    • 如果 arr[mid - 1] 小于 arr[mid],则局部最小值在左半部分,更新右边界 right = mid - 1
    • 如果 arr[mid + 1] 小于 arr[mid], 则局部最小值在右半部分,更新左边界 left = mid + 1

通过使用二分查找的变种算法,可以高效地在无序数组中找到一个局部最小值。这个算法在大规模数据的查找中表现出色,时间复杂度为 O(log n)。

算法实现

以下是使用二分查找法找到局部最小值的 Python 实现:

def find_local_minimum(arr):
    n = len(arr)

    if n == 0:
        return -1
    if n == 1:
        return -1

    if arr[0] <= arr[1]:
        return 0
    if arr[n - 1] <= arr[n - 2]:
        return n - 1

    left, right = 0, n - 1

    while left <= right:
        mid = left + (right - left) // 2

        if arr[mid] <= arr[mid - 1] and arr[mid] <= arr[mid + 1]:
            return mid
        elif mid > 0 and arr[mid - 1] < arr[mid]:
            right = mid - 1
        else:
            left = mid + 1

    return None

def getLessIndex(arr):
    if arr == None or len(arr)==0:
        return -1
    if len(arr) == 1 or arr[0] < arr[1]:
        return 0
    lens = len(arr)
    if arr[lens-1] < arr[lens-2]:
        return lens - 1

    left = 1
    right = lens - 2
    mid = 0
    while left < right:
        mid = left + ((right - left) >> 1)
        if arr[mid] > arr[mid-1]:
            right = mid - 1
        elif arr[mid] > arr[mid+1]:
            left = mid + 1
        else:
            return mid
    return left

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948376.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《Rust权威指南》学习笔记(五)

高级特性 1.在Rust中&#xff0c;unsafe是一种允许绕过Rust的安全性保证的机制&#xff0c;用于执行一些Rust默认情况下不允许的操作。unsafe存在的原因是&#xff1a;unsafe 允许执行某些可能被 Rust 的安全性检查阻止的操作&#xff0c;从而可以进行性能优化&#xff0c;如手…

云备份项目--客户端编写

文章目录 10. 客户端工具类10.1 整体的类10.2 测试 11 客户端数据管理类11.1 整体的类11.2 测试 12. 客户端业务处理12.1 整体的类 完整的代码–gitee链接 10. 客户端工具类 10.1 整体的类 在windows平台下进行开发&#xff0c;Util.hpp实际上是客户端FileUtil.hpp和JsonUtil…

开发培训-慧集通(iPaaS)集成平台脚本开发Groovy基础培训视频

‌Groovy‌是一种基于Java虚拟机&#xff08;JVM&#xff09;的敏捷开发语言&#xff0c;结合了Python、Ruby和Smalltalk的许多强大特性。它旨在提高开发者的生产力&#xff0c;通过简洁、熟悉且易于学习的语法&#xff0c;Groovy能够与Java代码无缝集成&#xff0c;并提供强大…

蓝桥杯(Java)(ing)

Java前置知识 输入流&#xff1a; &#xff08;在Java面向对象编程-CSDN博客里面有提过相关知识------IO流&#xff09; // 快读快写 static BufferedReader in new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter out new BufferedWriter(new…

【2025最新计算机毕业设计】基于SpringBoot+Vue智慧养老医护系统(高质量源码,提供文档,免费部署到本地)【提供源码+答辩PPT+文档+项目部署】

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

文献分享集:跨模态的最邻近查询RoarGraph

文章目录 1. \textbf{1. } 1. 导论 1.1. \textbf{1.1. } 1.1. 研究背景 1.2. \textbf{1.2. } 1.2. 本文的研究 1.3. \textbf{1.3. } 1.3. 有关工作 2. \textbf{2. } 2. 对 OOD \textbf{OOD} OOD负载的分析与验证 2.1. \textbf{2.1. } 2.1. 初步的背景及其验证 2.1.1. \textbf{2…

【读书笔记·VLSI电路设计方法解密】问题35:ASIC设计流程的两个主要方面是什么

毫无疑问,ASIC设计流程是一个复杂的系统,包含了许多商业CAD工具以及许多内部开发的工具或脚本。然而,无论流程中集成了多少工具或脚本,ASIC设计流程的核心目标始终可以归结为两个关键点:创建和检查。 创建过程指的是生成硬件的活动,例如RTL编码、逻辑综合以及布局布线。…

域上的多项式环,整除,相通,互质

例1.已知 (R,,x)为域&#xff0c;请选出正确的说法:(A)(R,,x)也是整区; ABCD (B)R中无零因子; C)R在x运算上满足第一、二、三指数律; (D)R只有平凡理想; (E)R只有平凡子环。 域的特征&#xff1a; 域中&#xff0c;非0元素的加法周期 思考、在模7整数环R,中&#xff0c;…

CSS3——3. 书写格式二

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><!--css书写&#xff1a;--><!--1. 属性名:属性值--><!--2.属性值是对属性的相关描述--><!--3.属性名必须是…

2街景两两对比程序,Trueskill计算评分代码,训练模型,预测街景

目录 0、Emeditor软件1、place pluse 2.0数据集2、街景主观感知两两对比程序3、Trueskill结果4、训练模型Resnet&#xff0c;Efficient&#xff0c;VIT等对比选择。5、模型预测6、其他数据处理/程序/指导&#xff01;&#xff01;&#xff01;优势&#xff1a;全网最全最细&am…

【React+TypeScript+DeepSeek】穿越时空对话机

引言 在这个数字化的时代&#xff0c;历史学习常常给人一种距离感。教科书中的历史人物似乎永远停留在文字里&#xff0c;我们无法真正理解他们的思想和智慧。如何让这些伟大的历史人物"活"起来&#xff1f;如何让历史学习变得生动有趣&#xff1f;带着这些思考&…

Golang学习历程【第五篇 复合数据类型:数组切片】

Golang学习历程【第五篇 复合数据类型&#xff1a;数组&切片】 1. 数组&#xff08;Array&#xff09;1.1 数组的定义1.2 初始化数组1.3 数据的循环遍历1.4 多维数组 2. 切片&#xff08;Slice&#xff09;2.1 切片声明、初始化2.2 基于数组创建切片2.2 切片的长度(len)和容…

ESP32自动下载电路分享

下面是一个ESP32系列或者ESP8266等电路的一个自动下载电路 在ESP32等模块需要烧写程序的时候&#xff0c;需要通过将EN引脚更改为低电平并将IO0引脚设置为低电平来切换到烧写模式。 有时候也会采用先将IO接到一个按键上&#xff0c;按住按键拉低IO0的同时重新上电的方式进入烧写…

【OceanBase】使用 Superset 连接 OceanBase 数据库并进行数据可视化分析

文章目录 前言一、前提条件二、操作步骤2.1 准备云主机实例2.2 安装docker-compose2.3 使用docker-compose安装Superset2.3.1 克隆 Superset 的 GitHub 存储库2.3.2 通过 Docker Compose 启动 Superset 2.4 开通 OB Cloud 云数据库2.5 获取连接串2.6 使用 Superset 连接 OceanB…

联发科MTK6771/MT6771安卓核心板规格参数介绍

MT6771&#xff0c;也被称为Helio P60&#xff0c;是联发科技(MediaTek)推出的一款中央处理器(CPU)芯片&#xff0c;可运行 android9.0 操作系统的 4G AI 安卓智能模块。MT6771芯片采用了12纳米工艺制造&#xff0c;拥有八个ARM Cortex-A73和Cortex-A53核心&#xff0c;主频分别…

修复 ITunes 在 Windows 或 Mac 上不断崩溃的问题 [100% 有效]

对于 iDevice 用户来说&#xff0c;只能通过 iTunes 在 iDevice 和计算机之间传输文件的困境一直是一个紧迫的问题。所有 iPhone 用户可能都知道&#xff0c;iTunes 并不是一款高效的应用程序&#xff0c;有时性能会很差&#xff0c;例如在 iDevices 和计算机之间传输文件时不断…

【AI大模型】深入GPT-2模型细节:揭秘其卓越性能的秘密

目录 &#x1f354; GPT2的架构 &#x1f354; GPT2模型的细节 2.1 模型过程 2.2 GPT2工作细节探究 &#x1f354; 小结 学习目标 掌握GPT2的架构掌握GPT2的训练任务和模型细节 &#x1f354; GPT2的架构 从模型架构上看, GPT2并没有特别新颖的架构, 它和只带有解码器模块…

C语言 - 理解函数栈帧

一&#xff1a;概述 函数栈帧是函数调用过程中为管理和存储函数相关信息&#xff08;如局部变量、返回地址等&#xff09;而在栈上分配的一块内存区域。它是实现函数调用、递归和返回的关键机制。 二&#xff1a;栈帧的组成 一个典型的栈帧通常包含以下内容&#xff08;从高地…

windows终端conda activate命令行不显示环境名

问题&#xff1a; 始终不显示环境名 解决 首先需要配置conda的环境变量 确保conda --version能显示版本 然后对cmd进行初始化&#xff0c;如果用的是vscode中的终端&#xff0c;那需要对powershell进行初始化 Windows CMD conda init cmd.exeWindows PowerShell conda …

检索增强生成 和思维链 结合: 如何创建检索增强思维链 (RAT)?

论文地址&#xff1a;https://arxiv.org/pdf/2403.05313 Github地址&#xff1a;https://github.com/CraftJarvis/RAT 想象一下&#xff0c;一个人工智能助手可以像莎士比亚一样写作&#xff0c;像专家一样推理。这听起来很了不起&#xff0c;对吧&#xff1f;但是&#xff0…