代码随想录二刷复习(二分法)

二分法模板:

1:左闭右闭区间写法

第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。

区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:

while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

点击查看代码
class Solution:def search(self, nums: List[int], target: int) -> int:left = 0right = len(nums) - 1while left <= right:mid = (left + right)//2if(target > nums[mid]):left = mid + 1if(target == nums[mid]):return midif(target < nums[mid]):right = mid - 1return -1

2:左闭右开

有如下两点:

while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]

点击查看代码
class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums)  # 定义target在左闭右开的区间里,即:[left, right)while left < right:  # 因为left == right的时候,在[left, right)是无效的空间,所以使用 <middle = left + (right - left) // 2if nums[middle] > target:right = middle  # target 在左区间,在[left, middle)中elif nums[middle] < target:left = middle + 1  # target 在右区间,在[middle + 1, right)中else:return middle  # 数组中找到目标值,直接返回下标return -1  # 未找到目标值
下面来看二分法代码随想录中的题目:

leetcode 35

在这里插入图片描述
题目给出了排序数组,很大概率就是使用二分查找,但是这里需要考虑的问题就是插入位置在哪里。这里我们考虑区间是左闭右闭的情况。

class Solution:def searchInsert(self, nums: List[int], target: int) -> int:left = 0right = len(nums) - 1while left <= right:mid = (left + right) // 2if(nums[mid] == target):return midif(nums[mid]>target):right = mid - 1if(nums[mid] < target):left = mid + 1return right + 1 

其余和二分查找没有区别,这里唯一需要注意的地方就是若未找到的话,返回索引可以有两种,left和right+1.这里的话可以自己找个例子写一下就可以了。
下面看这道题:

leetcode 34

在这里插入图片描述
你的理解基本上是正确的,尤其是关于使用两次二分查找来分别确定目标值的左边界和右边界的方法。下面我会进一步详细解释这个过程,确认你的理解,并补充一些可能的细节。

寻找右边界

当使用二分查找寻找右边界时,关键在于确保不错过最右侧的目标值。这可以通过以下步骤实现:

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

  2. 循环条件while left <= right

  3. 中间索引mid = (left + right) // 2

  4. 比较逻辑

    • 如果 nums[mid] == target,则更新 left = mid + 1。这是因为我们需要确认是否有更靠右的相同目标值,所以我们将搜索范围向右推进。
    • 如果 nums[mid] > target,则更新 right = mid - 1
    • 如果 nums[mid] < target,则更新 left = mid + 1
  5. 循环结束后:由于 left 最终指向目标值最后一次出现位置的下一个位置,所以正确的右边界是 left - 1

寻找左边界

寻找左边界的方法与寻找右边界类似,但方向相反:

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

  2. 循环条件while left <= right

  3. 中间索引mid = (left + right) // 2

  4. 比较逻辑

    • 如果 nums[mid] == target,则更新 right = mid - 1。这是因为我们需要确认是否有更靠左的相同目标值,所以我们将搜索范围向左推进。
    • 如果 nums[mid] > target,则更新 right = mid - 1
    • 如果 nums[mid] < target,则更新 left = mid + 1
  5. 循环结束后:由于 right 最终指向目标值第一次出现位置的前一个位置,所以正确的左边界是 right + 1

结果验证

  • 目标值存在:左边界应该指向目标值的第一个位置,右边界应该指向目标值的最后一个位置。
  • 目标值不存在:如果目标值不存在,左边界和右边界的差应该正好为1,因为 right 停在小于目标值的最大位置,而 left 停在大于目标值的最小位置。

你的理解是正确的,而且你已经很好地掌握了二分查找在这种情况下的应用。这种方法确保了高效地找到目标值的确切位置或者确定其不存在。
具体程序如下:

class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:leftBoder = self.getleftboard(nums, target)rightBoder = self.getrightboard(nums, target)# 情况一if leftBoder == -2 or rightBoder == -2: return [-1, -1]# 情况三if rightBoder -leftBoder >1: return [leftBoder + 1, rightBoder - 1]# 情况二return [-1, -1]def getrightboard(self,nums,target):left = 0right = len(nums) - 1rightboard = -2while left <= right:mid = left + (right - left) // 2if nums[mid] > target:right = mid - 1else:left = mid + 1rightboard = leftreturn rightboarddef getleftboard(self,nums,target):left = 0right = len(nums) - 1leftboard = -2while left <= right:mid = left + (right - left) // 2if nums[mid] >= target:right = mid - 1leftboard = rightelse:left = mid + 1return leftboard

leetcode 69

在这里插入图片描述
在二分查找中,寻找左边界、右边界和寻找特定条件的最大或最小值虽然共享同样的基本结构,但确实存在一些关键的差异。我们可以通过比较这些方法的细节来理解这些差异。

当我们寻找左边界时,目标是找到数组中第一个等于目标值的元素的位置。对于这种情况,我们通常会在找到目标值时继续向左搜索(缩小右边界),以确保没有更早出现的相同值。
寻找右边界的目的是找到数组中最后一个等于目标值的元素的位置。在这种情况下,即使找到了目标值,我们也会继续向右搜索(增加左边界),以确保没有更晚出现的相同值。
在寻找特定条件下的最大或最小值时,如求整数 ( x ) 的平方根,我们的目标是找到最大的整数 ( k ),使得 ( k^2 \leq x )。这种情况下的二分查找与寻找右边界有点相似,因为我们在满足条件的情况下向右推进左边界,以尽可能增大 ( k ) 的值。当 ( k^2 ) 大于 ( x ) 时,我们需要减小 ( k )(缩小右边界)。
所以程序按照寻找右边界的写即可,返回left-1即可。

class Solution:def mySqrt(self, x: int) -> int:left = 1right = xif x == 0:return 0if x == 1:return 1while left <= right:mid = left +(right - left)//2if mid*mid > x:right = mid - 1else:left = mid + 1return left - 1

下面继续看一道类似的题目:

leetcode367

在这里插入图片描述
这道题其实我们完全可以接着上面69题的思路去做,稍加修改,因为上道题寻找的是右边界也就是刚好是第一个平方和大于num的数,所以我们再去计算下left-1的平方和是否等于num,如果等于就是有效的完全平方数,反之则不是。
具体程序如下:

class Solution:def isPerfectSquare(self, num: int) -> bool:left = 1right = numif num == 1:return Truewhile left <= right:mid = left +(right - left)//2if mid*mid > num:right = mid - 1else:left = mid + 1if right * right == num:return Trueelse:return False

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue 给特定满足条件的表单数据添加背景颜色,组件的 row-class-name

1、:row-class-name"tableRowClassName" 可为表格每行根据后面的函数绑定class名 <!-- 列表框 --><div class"tableList"><el-table :data"teamModelListTable" style"width: 100%"selection-change"handleSele…

el-table表格操作列错行处理

解决方法&#xff1a; <style>::v-deep .el-table th.el-table__cell > .cell {white-space: nowrap !important;} </style>

不想填邀请码?Xinstall来帮你,一键安装无忧愁

在这个快节奏的时代&#xff0c;每一个点击都承载着用户的期待与耐心。然而&#xff0c;在下载App的过程中&#xff0c;繁琐的邀请码填写往往成为了用户体验的一大障碍。你是否也曾经因为不愿填写邀请码而放弃了一款心仪的App&#xff1f;今天&#xff0c;就让我们一起走进Xins…

镜像与容器

Docker Image (镜像) Docker 镜像概念 Docker iamge 本质上是一个 read-only 只读文件&#xff0c;这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必需的文件。 可以把 Docker image 理解成一个模板&#xff0c;可以通过这个模板实例化出来很多…

【Datawhale AI 夏令营】入门lightgbm及特征工程进行实践

文章目录 1. LightGBM简介2. 导入必要的库3. 加载数据集4. 数据可视化4.1 不同类型对应目标值的柱状图4.2 特定ID的目标值折线图 5. 特征工程5.1 合并训练集和测试集并进行排序5.2 历史平移5.3 窗口统计5.4 数据切分5.5 确定输入特征 6. 模型训练与评估7. 结果展示 1. LightGBM…

一文看懂JTAG基本知识

文章目录 1、JTAG是什么?1.1边界扫描2、JTAG如何起作用?2.1 PC控制JTAG2.2 并行端口2.3 JTAG TAP控制器2.4 计算JTAG链中元件个数2.5 获得JTAG链上芯片的ID3、边界扫描3.1、SAMPLE3.2、边界扫描寄存器3.3、JTAG还可以做什么?参考资料:1、JTAG是什么? JTAG是20世纪80年代开…

云监控(华为) | 实训学习day1(10)

云监控&#xff1a;确保服务器高效运行 在当今的数字化时代&#xff0c;服务器的稳定运行对于任何企业都至关重要。为了确保服务器的 CPU、内存和硬盘等资源的合理运行&#xff0c;云监控成为了一项不可或缺的技术。本文将详细介绍云监控的基本概念、所需软件、配置方法以及如何…

JDBC 技术 | Java连接MySQL数据库(四万字零基础保姆级超全详解)

文章目录 前言一. JDBC概述1. JDBC 概念2. JDBC 本质3. JDBC 的好处 二. JDBC 快速入门1. 编写Java 程序步骤2. 在IDEA 中的操作流程3. 正式编写 Java程序 三. JDBC API详解1. DriverManager 类2. Connection 接口2.1 获取执行SQL语句的对象 3 .ResultSet 类3.1 概述3.2 代码实…

Cadence23学习笔记(四)

这个人讲cadence也很不错&#xff1a; 73、创建Power NetClass[Cadence Allegro132讲视频教程字幕版]_哔哩哔哩_bilibili 上位机开发&#xff1a; MFC 最详细入门教程-CSDN博客 Board Geometry — Design_Outline 板框 Etch — Top 走线 Pin — Top 焊盘 …

探索APP开发中的主流版式设计与应用实践

在当今移动互联网高速发展的时代&#xff0c;APP已成为人们日常生活中不可或缺的一部分。无论是社交娱乐、购物支付还是工作学习&#xff0c;各类APP都以其独特的界面设计和用户体验赢得了用户的青睐。而APP开发的版式设计和页面规范&#xff0c;则是决定用户体验好坏的关键因素…

记录些MySQL题集(6)

MySQL 单表为什么不要超过 2000W 行&#xff1f; 数据持久化在磁盘中&#xff0c;磁盘的最小单元是扇区&#xff0c;一个扇区 0.5 KB&#xff0c;而由 8 个扇区可以构成一个文件系统块&#xff08;4K&#xff09;&#xff0c;以 InnoDB 存储引擎为例&#xff0c;一个数据页的大…

打卡第15天------二叉树

最近公司给我派活儿太多了,要干好多活儿,好多工作任务要处理,我都没时间刷题了。leetcode上的题目通过数量一直停留在原地不动,我真的很着急呀,我现在每天过的都有一种紧迫感,很着急,有一种与时间赛跑的感觉,真的时间过的太快了,没有任何人能够阻挡住时间的年轮向前推…

【异步爬虫:利用异步协程抓取一部电影】

利用异步协程抓取一部电影 我们把目光转向wbdy. 目前该案例还是可以用的. 我们想要抓取网上的视频资源就必须要了解我们的视频网站是如何工作的. 这里我用91看剧来做举例. 其他网站的原理是一样的. 1.视频网站是如何工作的 假设, 你现在想要做一个视频网站. 也有很多的UP猪…

【BUG】已解决:java.lang.IllegalStateException: Duplicate key

已解决&#xff1a;java.lang.IllegalStateException: Duplicate key 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市…

【数学建模】——多领域资源优化中的创新应用-六大经典问题解答

目录 题目1&#xff1a;截取条材 题目 1.1问题描述 1.2 数学模型 1.3 求解 1.4 解答 题目2&#xff1a;商店进货销售计划 题目 2.1 问题描述 2.2 数学模型 2.3 求解 2.4 解答 题目3&#xff1a;货船装载问题 题目 3.1问题重述 3.2 数学模型 3.3 求解 3.4 解…

超详细信息收集篇

1 域名信息收集 1.1 域名是什么 域名&#xff08;英语&#xff1a;Domain Name&#xff09;&#xff0c;又称网域&#xff0c;是由一串用点分隔的名字组成的 Internet 上某一台 计算机 或计算机组的名称&#xff0c;用于在数据传输时对计算机的定位标识&#xff08;有时也指地…

数据结构——栈和队列(C语言实现)

写在前面&#xff1a; 栈和队列是两种重要的线性结构。其也属于线性表&#xff0c;只是操作受限&#xff0c;本节主要讨论的是栈和队列的定义、表示方法以及C语言实现。 一、栈和队列的定义与特点 栈&#xff1a;是限定仅在表尾进行插入和删除的线性表。对栈来说&#xff0c;表…

【经验分享】关于静态分析工具排查 Bug 的方法

文章目录 编译器的静态分析cppcheck安装 cppcheck运行 cppcheck 程序员的日常工作&#xff0c;不是摸鱼扯皮&#xff0c;就是在写 Bug。虽然这是一个梗&#xff0c;但也可以看出&#xff0c;程序员的日常一定绕不开 Bug。而花更少的时间修复软件中的 Bug&#xff0c;且不引入新…

lightgbm

lightGBM 1.sklearn 使用代码 【机器学习基础】XGBoost、LightGBM与CatBoost算法对比与调参 首先&#xff0c;XGBoost、LightGBM和CatBoost都是目前经典的SOTA&#xff08;state of the art&#xff09;Boosting算法&#xff0c;都可以归类到梯度提升决策树算法系列。三个模…

5. JavaSE ——【适合小白的数组练习题】

&#x1f4d6;开场白 亲爱的读者&#xff0c;大家好&#xff01;我是一名正在学习编程的高校生。在这个博客里&#xff0c;我将和大家一起探讨编程技巧、分享实用工具&#xff0c;并交流学习心得。希望通过我的博客&#xff0c;你能学到有用的知识&#xff0c;提高自己的技能&a…