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

二分法模板:

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://xiahunao.cn/news/3247020.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

函数定义、合约与面向对象(以太坊solidity合约)

函数定义、合约与面向对象&#xff08;以太坊solidity合约&#xff09; 1-函数定义、构造与多态2-事件日志3-面向对象特征 1-函数定义、构造与多态 创建合约就是创建类&#xff0c;部署合约就是实例化 合约的方法还支持多态 还能使用第三方的库进行开发 整个合约部署后&…

运维管理数智化:数据与智能运维场景实践

本文来自腾讯蓝鲸智云社区用户&#xff1a;CanWay 摘要&#xff1a;笔者根据自身的技术和行业理解&#xff0c;分享嘉为蓝鲸数据与智能运维场景实践。 涉及关键字&#xff1a;一体化运维、平台化运维、数智化运维、AIOps、运维PaaS、运维工具系统、蓝鲸等。 本文作者&#xf…

自动驾驶AVM环视算法–全景和标定全功能算法实现和exe测试demo

参考&#xff1a;全景和标定全功能算法实现和exe测试demo-金书世界 1、测试环境 opencv310vs2022 2、使用的编程语言 c和c 3、测试的demo的获取 更新&#xff1a;测试的exe程序&#xff0c;无需解压码就可以体验算法测试效果 百度网盘&#xff1a; 链接&#xff1a;http…

minio 获取预览地址

1.进入到 minio&#xff0c;并设置桶的权限。 2.获取预览地址代码如下&#xff1a; 注意&#xff1a; GetPresignedObjectUrlArgs.builder().method(Method.GET)&#xff0c;这个地方一定要用 GET&#xff0c;我当时按照官网的例子写的&#xff0c;没注意这个&#xff0c;搞了…

深入解析公有IP与私有IP:地址分配与使用限制

IP地址在网络基础设施的建设和维护过程中起着至关重要的作用。作为IP地址的两大类型&#xff0c;公有IP和私有IP各自具有独特的分配机制和使用限制。本文将详细分析两者之间的区别&#xff0c;以帮助读者更好地理解和使用IP地址。 1. 公有IP与私有IP概述 IP地址是网络中的唯一…

库迪“夏日果咖季”打卡活动走样,联营商不想配合了?

库迪的“夏日果咖季”打卡活动&#xff0c;真是让人在这个炎炎夏日受一肚子气。 有大批不同IP的网友在社交媒体平台吐槽&#xff0c;特意前去门店打卡&#xff0c;却被告知门店没有这个活动。 一位广州的网友在小红书发帖表示&#xff0c;上班前特意坐地铁去门店参加活动&…

半自动辅助制作数据集【实例分割】

利用yoloV8的实例分割模型&#xff0c;半自动辅助制作数据集 引言&#xff1a;【主要步骤】 步骤1&#xff1a;无人机航拍&#xff0c;收集基础图片 步骤2&#xff1a;将收集到的图片&#xff0c;全部用yoloV8-seg.pt模型进行实例分割【预测之前&#xff0c;将配置文件default.…

什么是大模型?(超详细)从入门到精通 一文读懂大模型的基本概念

1. 大模型的定义 大模型是指具有大规模参数和复杂计算结构的机器学习模型。这些模型通常由深度神经网络构建而成&#xff0c;拥有数十亿甚至数千亿个参数。大模型的设计目的是为了提高模型的表达能力和预测性能&#xff0c;能够处理更加复杂的任务和数据。大模型在各种领域都有…

海外社媒矩阵为何会被关联?如何IP隔离?

在当今的数字时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分。通过社交媒体&#xff0c;人们可以与朋友互动&#xff0c;分享生活&#xff0c;甚至进行业务推广和营销。然而&#xff0c;社交媒体账号关联问题逐渐受到广泛关注。社交媒体账号为何会关联&#…

力扣经典题目之->删除有序数组中的重复项讲解 的讲解与实现

一&#xff1a;题目 二&#xff1a;思路讲解 第一步&#xff1a;创建两个下标&#xff0c;一个是第一个元素的&#xff08;start0&#xff09;&#xff0c;一个是第二个元素的&#xff08;end1&#xff09; 第二步&#xff1a; a&#xff1a;end移动&#xff0c;直到遇到不等…

Flowable-会签与或签

一、会签 会签的意思是&#xff0c;在流程任务管理中&#xff0c;任务通常是由一个人或者多个人同时去处理的&#xff0c;这种任务叫做会签任务。类似于并行网关&#xff0c;会签任务一般需要任务候选人全部完成审批后&#xff0c;才能进入下一个审批环节。 (一) 会签类型 按…

持续集成06--Jenkins构建触发器

前言 在持续集成&#xff08;CI&#xff09;的实践中&#xff0c;构建触发器是自动化流程中不可或缺的一环。它决定了何时启动构建过程&#xff0c;从而确保代码变更能够及时地得到验证和反馈。Jenkins&#xff0c;作为业界领先的CI/CD工具&#xff0c;提供了多种构建触发器选项…

jeecgboot项目不知道什么原因启动出来8080端口后就不下去了,要等上10多分钟才出来接口地址等正常情况

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、项目中途不知道什么原因&#xff0c;就出现下面情况 具体如下&#xff1a; 2024-07-15 15:08:15.767 [main] [34mINFO [0;39m [36mliquibase.changelog:30[0;39m - Reading from jeec…

什么是鉴权开发框架?如何认证和限流

目录 一、鉴权开发框架介绍二、Django REST framework是什么三、如何实现认证、权限与限流功能四、Django REST framework的应用场景 一、鉴权开发框架介绍 鉴权开发框架是一种用于实现身份验证和授权的软件开发工具。它可以帮助开发者快速构建安全、可靠的身份验证和授权系统…

Spring Boot 中使用 Resilience4j 实现弹性微服务的简单了解

1. 引言 在微服务架构中&#xff0c;服务的弹性是非常重要的。Resilience4j 是一个轻量级的容错库&#xff0c;专为函数式编程设计&#xff0c;提供了断路器、重试、舱壁、限流器和限时器等功能。 这里不做过多演示&#xff0c;只是查看一下官方案例并换成maven构建相关展示&…

DNS查询过程

DNS&#xff08;域名系统&#xff0c;Domain Name System&#xff09;是一个用于将域名和IP地址相互映射的系统。当你在浏览器中输入一个网址时&#xff0c;浏览器会通过DNS查询过程来找到对应的IP地址&#xff0c;以便能够连接到目标服务器。其查询过程一般通过以下步骤&#…

Netgear WN604 downloadFile.php 信息泄露漏洞复现(CVE-2024-6646)

0x01 产品简介 NETGEAR WN604是一款由NETGEAR(网件)公司生产的无线接入器(或无线路由器)提供Wi-Fi保护协议(WPA2-PSK, WPA-PSK),以及有线等效加密(WEP)64位、128位和152位支持,保障网络安全。同时支持MAC地址认证、802.1x RADIUS以及EAP TLS、TTLS、PEAP等安全机制,…

【Flowable | 第四篇】flowable工作流多任务实例节点实现会签/或签

文章目录 5.flowable工作流多任务实例节点实现会签/或签5.1会签/或签概念5.2多实例配置说明5.3会签例子5.3.1用户候选人配置5.3.2多实例配置5.3.3执行监听器配置5.3.5测试 5.flowable工作流多任务实例节点实现会签/或签 5.1会签/或签概念 我们在本篇中&#xff0c;将使用多任…

【JavaEE】synchronized原理详解

本文使用的是JDK1.8 目录 引言 Java对象在JVM的结构 对象头 Mark Word Monitor Owner EntryList WaitSet 加锁过程 锁消除 偏向锁 偏向锁使用 重偏向 撤销偏向 轻量级锁 重量级锁 自旋优化 引言 对于synchronized原理讲解之前&#xff0c;我们需要知道Java对象…

C#学习

C#学习 1.B站丑萌气质狗C#的循环-判断泛型错误处理面向对象static的使用定义showInfo类和Hero类 在这里插入图片描述 然后在该解决方案add新建一个类库&#xff0c;点击rebuild&#xff0c;会在bin文件夹下生成.dll文件 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direc…