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: "…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...