LeetCode - 二分查找(Binary Search)算法集合(Python)[左右边界|旋转数组|双列表]
欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/139419653

二分查找,也称为折半查找,是一种在有序数组中查找特定元素的高效算法。其基本原理是将待搜索的区间分成两半,然后根据中间元素与目标值的比较结果来确定下一步搜索的区间。这个过程会一直重复,直到找到目标元素或者搜索区间为空。二分查找,重要的是如何划分区间范围,移动左右指针。
二分查找的不同类型,包括:
- 基础的二分查找,包括各种不同形式,例如平方根、有序数组的单一元素
- 连续数左右边界的二分查找,熟练使用左右指针
- 旋转排序数组的二分查找,包括连续和不连续形式
- 双列表的联合二分查找
待做题目:
- 69. x 的平方根 、540. 有序数组中的单一元素
- 34. 在排序数组中查找元素的第一个和最后一个位置
- 33. 搜索旋转排序数组、81. 搜索旋转排序数组 II、153. 寻找旋转排序数组中的最小值、154. 寻找旋转排序数组中的最小值 II
- 4. 寻找两个正序数组的中位数
1. 二分查找
69. x 的平方根 - 二分查找,中值计算,注意细节,避免除数是0,默认返回r(右指针)
class Solution:def mySqrt(self, x: int) -> int:"""二分法,时间空间复杂度时间O(logx),空间O(1)"""l, r = 0, x # 左右指针res = 0 # 最终值while l <= r: # 左小于右mid = l + (r - l) // 2 # 计算中值if mid == 0: # 避免除数是0return rs = x // midif mid <= s:res = mid # res取小值l = mid + 1else:r = mid - 1return res
540. 有序数组中的单一元素 - 二分查找
class Solution:def singleNonDuplicate(self, nums: List[int]) -> int:"""时间复杂度 O(logn),空间复杂度 O(1)第1个元素下标是偶数,第2个元素下标是奇数"""n=len(nums)l,r=0,n-1while l<r:mid=l+(r-l)//2 # 计算中值if mid%2==0: # 中值是偶数位置if mid+1<n and nums[mid]==nums[mid+1]: # 常规条件l=mid+1 # 左移坐标else:r=midelse:if mid-1>=0 and nums[mid]==nums[mid-1]: # 常规条件l=mid+1 # 左移坐标else:r=midreturn nums[l] # 返回
2. 连续数左右边界的二分查找
34. 在排序数组中查找元素的第一个和最后一个位置 - 二分查找连续数的左右边界,注意:如何获得左边界和右边界,即先移动 r 还是先移动 l 的区别,同时注意右边界的位置-1。
class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:"""如何获取左右边界的问题,非常有趣,二分查找。时间复杂度O(logn),空间O(1)"""def bs(nums, t, is_l):n = len(nums)l, r = 0, n - 1res = n # 初始化最大值while l <= r:mid = l + (r-l) // 2 # 判断是大于t,还是大于等于t# low-True nums[mid]>=t,优先r左移,其次l右移,r<l, res值小# high-False nums[mid]>t,优先l左移,其次r右移,r>l,res值大if (is_l and nums[mid] >= t) or nums[mid] > t:r = mid - 1res = mid # 保存大值else:l = mid + 1# print(f"[Info] is_l: {is_l}, r: {r}, l: {l}, mid: {nums[mid]}, t: {t}")return resn = len(nums)l = bs(nums, target, True)r = bs(nums, target, False) - 1 # 大于是前1位if l <= r and nums[l] == target and nums[r] == target:return [l, r]else:return [-1, -1]
3. 旋转数组的二分查找
33. 搜索旋转排序数组 - 旋转排序的二分查找
class Solution:def search(self, nums: List[int], target: int) -> int:"""旋转数组,只有一侧是有序的,只搜索有序一侧的值。时间O(logn),空间O(1)"""n = len(nums)l, r = 0, n-1while l <= r:mid = l + (r-l) // 2 # 经典双指针起始if nums[mid] == target:return mid # 返回位置# 只搜索有序的一侧,即只移动有序的一侧的指针if nums[0] <= nums[mid]: # 左侧有序if nums[l] <= target < nums[mid]: # target左侧r = mid - 1 # 移动右指针else: # target右侧l = mid + 1 # 移动左指针else: # 右侧有序if nums[mid] < target <= nums[r]: # target右侧l = mid + 1 # 移动左指针else:r = mid - 1 # 移动右指针return -1 # 返回未找到
81. 搜索旋转排序数组 II - 旋转排序的二分查找,进阶含有重复元素
class Solution:def search(self, nums: List[int], target: int) -> bool:"""旋转数组,只有一侧是有序的,只搜索有序一侧的值,有相同元素时间O(logn),空间O(1)"""n = len(nums)l, r = 0, n-1while l <= r:mid = l + (r-l) // 2 # 经典双指针起始if nums[mid] == target:return True # 返回位置if nums[mid] == nums[l]:l += 1 # 解决相同元素elif nums[mid] == nums[r]:r -= 1 # 解决相同元素elif nums[mid] < nums[r]: # 右区间是增序的if nums[mid] < target <= nums[r]: # target右侧l = mid + 1 # 移动左指针else:r = mid - 1 # 移动右指针else: # 左区间是增序的if nums[l] <= target < nums[mid]: # target左侧r = mid - 1 # 移动右指针else: # target右侧l = mid + 1 # 移动左指针return False # 返回未找到
153. 寻找旋转排序数组中的最小值 - 旋转排序的二分查找,注意和最右值比较,判断区间。
class Solution:def findMin(self, nums: List[int]) -> int:"""时间复杂度 O(logn),空间复杂度 O(1)"""n = len(nums)l, r = 0, n-1while l < r:mid = l + (r-l) // 2# 中值小于右边界if nums[mid] <= nums[r]: # 避免l越界,优先移动rr = midelse: # 中值大于右边界l = mid+1return nums[l]
154. 寻找旋转排序数组中的最小值 II - 旋转排序的二分查找,包含重复数字
class Solution:def findMin(self, nums: List[int]) -> int:"""时间复杂度 O(logn),空间复杂度 O(1)"""n = len(nums)l, r = 0, n - 1while l <= r:mid = l + (r-l)//2 # 计算中值if nums[mid]<nums[r]:r = midelif nums[mid]>nums[r]:l = mid+1else:r -= 1 # 避免重复return nums[l]
4. 双列表的联合二分查找
4. 寻找两个正序数组的中位数 - 双列表联合二分查找
class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:"""时间复杂度O(log(m+n)),空间复杂度O(1)"""n1 = len(nums1)n2 = len(nums2)if n1 > n2:return self.findMedianSortedArrays(nums2,nums1)k = (n1 + n2 + 1)//2 # 中值l, r = 0, n1while l < r:m1 = l +(r - l)//2m2 = k - m1if nums1[m1] < nums2[m2-1]:l = m1 + 1else:r = m1m1 = lm2 = k - m1 c1 = max(nums1[m1-1] if m1 > 0 else float("-inf"), nums2[m2-1] if m2 > 0 else float("-inf") )if (n1 + n2) % 2 == 1:return c1c2 = min(nums1[m1] if m1 < n1 else float("inf"), nums2[m2] if m2 <n2 else float("inf"))return (c1 + c2) / 2
参考:
- CSDN - 二分法的专题总结——到底应该写小于还是小于等于、两个判断还是三个判断
- 二分查找
相关文章:
LeetCode - 二分查找(Binary Search)算法集合(Python)[左右边界|旋转数组|双列表]
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/139419653 二分查找,也称为折半查找,是一种在有序数组中查找特定元素的高效算法。其基本原理是将待搜索的区间分成两半&am…...
android睡眠分期图
一、效果图 做医疗类项目,经常会遇到做各种图表,本文做的睡眠分期图。 二、代码 引入用到的库 api joda-time:joda-time:2.10.1 调用代码 /*** 睡眠* 分期*/private SleepChartAdapter mAdapter;private SleepChartAttrs mAttrs;private List<SleepI…...
2023年信息素养大赛小学组C++智能算法复赛真题
今天给大家分享2023年全国青少年信息素养大赛小学组C智能算法挑战赛复赛里面的一套真题,希望有助于大家了解复赛的难度及备考。 其他真题下载:网盘-真题-信息素养大赛...
独立游戏开发的 6 个步骤
💂 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】🤟 一站式轻松构建小程序、Web网站、移动应用:👉注册地址🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交…...
Stable Diffusion AI绘画:从创意词汇到艺术图画的魔法之旅
文章目录 一、Stable Diffusion的工作原理二、从提示词到模型出图的过程三、Stable Diffusion在艺术创作中的应用《Stable Diffusion AI绘画从提示词到模型出图》内容简介作者简介楚天 目录前言/序言本书特色特别提示 获取方式 在科技的飞速发展中,Stable Diffusion…...
使用C++实现高效的套接字连接池
在现代网络应用中,高效管理网络连接是实现高并发和低延迟的重要因素。下面将详细介绍如何使用C实现一个高效的套接字连接池,以便在需要时快速复用连接,从而提高系统性能和资源利用率。 一、什么是连接池? 连接池是一种管理网络连…...
个人百度百科怎么创建
编辑百度词条是一个相对简单的流程,但需要注意的是,并不是所有的词条都可以编辑,部分锁定的词条是无法编辑的,但可以通过官方平台申请解封。以下百科优化网yajje分享是详细的步骤: 注册百度账号 首先,用户…...
Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:潍柴雷沃智慧农业无人驾驶
潍柴雷沃智慧农业科技股份有限公司,是潍柴集团重要的战略业务单元,旗下收获机械、拖拉机等业务连续多年保持行业领先,是国内少数可以为现代农业提供全程机械化整体解决方案的品牌之一。潍柴集团完成对潍柴雷沃智慧农业战略重组后,…...
ICPC训练赛补题集
ICPC训练赛补题集 文章目录 ICPC训练赛补题集D - Fast and Fat (负重越野)I-路径规划G. Inscryption(邪恶铭刻)NEW Houses雪中楼(西安交通大学)L.BracketGenerationE - Checksum D - Fast and Fat (负重越野) 原题链接:原题链接 题意:体重大的背体重小的…...
The First项目报告:解读去中心化衍生品交易所AVEO
2023 年12月8日凌晨,Solana 生态 MEV 基础设施开发商 Jito Labs 开放了 JTO 空投申领窗口,JTO 的价格在开盘短暂震荡后迅速攀高,一度触及 4.94 美元。 JTO 是加密社区这两日关注的热门标的,而在这场讨论中,除 Solana …...
Docker 快速更改容器的重启策略(Restart Policies)以及重启策略详解
目录 1. 使用 docker update 命令2. 在启动容器时指定重启策略3. 在 Docker Compose 文件中指定重启策略4. 总结 官方文档:Start containers automatically 1. 使用 docker update 命令 Docker 提供了 docker update 命令,可以在容器运行时更改其重启策…...
docker 启动关闭,设置仓库地址
1. 配置/etc/docker/daemon.json cat /etc/docker/daemon.json# 内容 {"registry-mirrors": ["https://0nth4654.mirror.aliyuncs.com"],"insecure-registries": ["harbor.domain.io"] }2. 配置systemd启动文件 和方法1配置会有冲突&a…...
二叉树的链式结构实现
前言 该篇是在二叉树介绍及堆-CSDN博客的基础上的。该篇会有点抽象大家要自己多画画图自己感受一下。现在我们开始吧! 在学习二叉树基本操作时,我们需要先有一个现成的二叉树。来方便我们练习。因为现在我们对二叉树的理解也并不是很深入。在这里创建一个…...
MySQL远程连接
文章目录 MySQL远程连接(Linux)一、更改MySQL配置文件二、进入MySQL修改用户表host值三、使用其他电脑即可远程访问数据库MySQL远程连接(Linux)一、修改my.ini中的配置文件二、修改用户权限三、远程连接 MySQL远程连接(Linux) 以下MySQL远程连接:MySQL部署环境为Ubu…...
奔驰大G升级电动踏板效果
奔驰大G车型的升级旋转电动踏板是一项非常实用的功能,它为驾驶者提供了诸多便利和舒适性。以下是关于这一功能的实用性介绍: 便利的上下车体验:旋转电动踏板可以在车辆停稳的情况下自动伸出,为乘客提供便利的上下车体验。特别是对…...
【xilinx】vivado中的xpm_cdc_gray.tcl的用途
背景 【Xilinx】vivado methodology检查中出现的critical Warning-CSDN博客 接上篇文章,在vivado进行 methodology检查时出现了严重警告,顺着指示查到如下一些问题 TIMING #1 Warning An asynchronous set_clock_groups or a set_false path (see con…...
windows中安装zookeeper
https://zhuanlan.zhihu.com/p/692451839 【zookeeper】在Windows上启动zookeeper_windows启动zk-CSDN博客 Index of /apache/zookeeper/zookeeper-3.9.2 Index of /apache/zookeeper/zookeeper-3.9.2 Zookeeper的应用场景 1、配置管理 2、服务注册中心 3、主从协调 4、…...
直接写和放在函数中不同的R语言用法
索引数据框中的某一列 df$A可以索引数据框df中列名为A的列的所有值。那么假如列名是一个R对象怎么做? df <- data.frame(A1:5, B(1:5)*2)df$A## [1] 1 2 3 4 5needed_column A# df$needed_column ? Wrong# 注意是双方括号 df[[needed_column]]## [1] 1 2 3 4…...
《mysql轻松学习·二》
1、创建数据表 contacts:数据表名 auto_increament:自动增长 primary key:主键 engineInnoDB default charsetutf8; 默认字符集utf8,不写就默认utf8 对数据表的操作: alter table 数据表名 add sex varchar(1); //添…...
Swift对比版本号
在 Swift 中比较两个版本号的大小可以使用以下方法: func compareVersions(_ version1: String, _ version2: String) -> ComparisonResult {let v1Components version1.components(separatedBy: ".")let v2Components version2.components(separatedBy: "…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
