【算法】【二分法】二分法详解

news2024/9/24 1:24:13

先给y总打一个广告。(我这种废物收不到钱)
本科时候就在打蓝桥杯玩玩算法,当时听朋友的一个刷题且涵盖教程的网站,ACWING。
www.acwing.com
里面好处是大部分基础算法都有,Y总的视频! y总我的神!!!!。
非常适合萌新学学算法之类的。废物(比如说我)全都忘光了也能进去看看

前几天刷LeetCode100刚好有一个算法思路使用二分作为一个优化,发现自己对于二分理解不是很到位,所以就回去研究了一下,发现之前确实缺失太多。。。。
但还好看几个小时也能弄懂了。

但我刷别人教程,感觉写的还不是很明白??索性自己记录一下。不然就可以Copy别人的了,可恶,没被我找到。

基础

二分基础非常好理解,算是作为一个intro部分。后面基本遇不到这么简单的环境感觉。

场景:给你一个单调递增的序列,让你找到其中的一个数。当然递增递减无所谓。但我们额外一个假设是所有数字在这个数组里面唯一。
好,这个就是一个二分的标准模板。
首先先明确一下我们的目标:我们用二分的目标是优化时间复杂度
假设说我现在不知道二分,那我肯定没啥办法,直接暴力循环一个一个看,那么这样子的时间复杂度就是O(N)
但如果使用二分的话,就能够直接将这个时间复杂度直接降到O(log n)

先理解一下算法思想:
这个场景式给定了一个具体的区间,首先我们可以先看一下区间的中点,那么这时候就有三种情况:

  1. 区间中点就是你要的target,这时候皆大欢喜,直接return。
  2. 区间中点比target小,那这时候一想,我区间中点都比我的target小,那么我的target一定在我的右边吧。这时候就可以把左边砍掉。
  3. 区间中点比target大,跟上面同理,右边就不用看了。

所以看2,3这两种情况,他都能将原本的区间砍半,然后变为原本区间的一半,那么就等价于我们最早的假设,在一个区间找一个数,只不过这个区间比原来少了一半。那不就递归了,可以写代码了。
也正是这个砍半,所以能够将原本时间复杂度降到log n

大致代码框架


func binarySearch(arr []int, al int, ar int, tar int) int {
	l, r := al, ar					// search的区间
	for l < r {
		mid := (l + r) >> 1
		if arr[mid] == tar {		// 根据条件,修改区间l,r
			return mid
		} else if arr[mid] > tar {
			r = mid - 1
		} else {
			l = mid + 1
		}
	}
	return l
}

进阶

首先,先来参透一下二分的本质。

刚刚那个intro里面,目标其实是降低复杂度。但是为什么能够降低复杂度,他的核心是什么?实际上他的核心在于他能够直接将一半的区间都不需要考虑。那么为什么他能够让一半的区间都不需要考虑?
因为这里的MID实际上代表了他右边(左边)的一整个群体,只要这个MID不满足条件,那么他的另外一半一定不满足

所以二分本质不是单调,而在于二分类,只不过单调这个性质很容易就能够达到二分类的效果

基于这个逻辑,我就更希望让刚刚基础版本考虑三种情况降到只考虑两种情况。(实际上是我瞎说的,只不过现在算法里面大家都考虑两种情况)

怎么弄成只考虑两种情况?很简单,还是按照刚刚环境,第一个不是 == 那你把他随便归类到其中一个,把其中一个改为 <= 或者另外一个改为 >= 就完事了。

那我怎么找到这个target?还是一样找吧,因为他还是在你的目标区间里面吧。
但很有意思的是两种分法使得,二分法变成了两种现象。刚刚提及归类有两种方法吧,一种可以将他归为左边,一种将他归为右边。

所以就变成了查找某个区间的端点。而这个值要么是你的target,要么就是比你的target恰好大一点或者小一点
在这里插入图片描述
也就是寻找图中红色端点,或者图中绿色的端点。

而这里对应这个两个模板


func BL(arr [] int, sl int, sr int, tar int) int {
    l, r := sl, sr
    
    for l < r {
        mid := (l + r + 1) >> 1		// 必有加
        if arr[mid] <= tar {
            l = mid
        } else {
            r = mid - 1 	// 有减
        }
    }
    
    return l
}

func BR(arr [] int, sl int, sr int, tar int) int {
    l, r := sl, sr
    
    for l < r {
        mid := (l + r) >> 1
        if arr[mid] >= tar {
            r = mid
        } else {
            l = mid + 1 	
        }
    }
    
    return l
}

上面代码的BL就对应查找图中红色端点,BR就对应查找图中蓝色端点。

解释一下代码更好背代码。

先解释红色:(这里场景还是用刚才那个,也就是数组单调递增等等)

首先,你找红色,那就是把你的target并到左边那边,而这里面的左边也就可以认为是所有比target小或者等这一类。

其次我们都假设true会怎么样,false会怎么样。

true的话就说明我的这个mid落在了红色这个区间,但是我是希望能够找到更为接近的右端点把?所以这时候我就需要更新l 为我的mid。因为这个mid依旧符合这个红色区间条件,所以我并不能把他排除。需要让他进行下一步考虑。
false的话就说明这个mid落在了绿色这个区间,那肯定是错的。所以这时候就要让r改为mid-1

然后仔细看 这里mid在算的时候,不是简单算中点,为什么?

  • 很简单,你套用区间只有两个数的情况,比如是1,2 而你的target是1.那这时候如果mid算中点,也就是 l + r >> 1,这时候结果就是0,还是这个1,结果是true, 所以就会调整 l=mid,那么这时候区间还是没有改变,就会进入到死循环,所以这里就有个+1

口诀有减必有加

同理,另外一个类似的推一下也就出来了,所以刚刚哪两个就是分别对应求不同区间的模板,自己看着用就行。

所以这时候就可以用二分法来解决很多问题。

acwing例题:789. 数的范围
标准的例题,做完应该就算会了

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

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

相关文章

设计模式——适配器设计模式

设计模式——适配器设计模式 适配器设计模式1.1 基本介绍1.2 工作原理1.3 类适配器模式1.3.1 基本介绍1.3.2 示例1.3.3 代码实现1.3.4 注意事项 1.4 对象适配器模式1.4.1 基本介绍1.4.2 示例1.4.3 代码实现1.4.4 注意事项 1.5 接口适配器模式1.5.1 基本介绍1.5.2 示例1.5.3 代码…

Web3 社交领域的开发技术

Web3 社交领域的开发技术主要包括以下几种&#xff0c;随着 Web3 技术的不断发展&#xff0c;Web3 社交领域将会出现更多新的技术和应用场景。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 区块链技术 区块链技术是 Web3 社交的…

在Rstudio中点一点就出来了一个R包

新建一个Package Build一个Package 更多开发指南 https://r-pkgs.org/

vscode使用及调试方式和技巧

常用快捷键 ctrl ~ 显示隐藏终端面板 Ctrl\ 快速拆分文件编辑 Alt ↑↓ 移动当前代码行的位置 CtrlD 选中当前匹配项 CtrlB 切换侧边栏 alt 单机左键 或 长按鼠标滚轮鼠标左键下拉 添加多处光标 Ctrlp 快捷键设置 vscode调试 2022年了&#xff0c;该学会用VSC…

通用详情页的打造

背景介绍 大家都知道&#xff0c;详情页承载了站内的核心流量。它的量级到底有多大呢&#xff1f; 我们来看一下&#xff0c;日均播放次数数亿次&#xff0c;这么大的流量&#xff0c;其重要程度可想而知。 在这样一个页面&#xff0c;每一个功能都是大量业务的汇总点。 作为…

RayLink企业版正式上线!

哈咯大家~我是小R 经过RayLink团队的努力&#xff0c;大家期待的RayLink企业版正式上线了&#xff0c;相对于传统的远程控制软件&#xff0c;企业版本更能满足对于企业的安全性&#xff0c;扩展性&#xff0c;以来满足企业不断变化的业务需求。 RayLink企业版&#xff1a;一站…

Android C++系列:Linux网络(二)通信过程

上图对应两台计算机在同一网段中的情况,如果两台计算机在不同的网段中,那么数据从一台计算机到另一台计算机传输过程中要经过一个或多个路由器,如下图所示其实在链路层之下还有物理层,指的是电信号的传递方式,比如现在以太网通用的网线 (双绞线)、早期以太网采用的的同轴电…

逆向之在浏览器上对window等对象进行hook

一般情况下&#xff0c;在chrome浏览器上使用JS对window document等对象是无法hook的&#xff0c;除非魔改浏览器底层代码&#xff0c;原因是因为对象的configurable属性为false 这样如果需要对document对象使用JS进行hook,首先需要一个可配置的chrome浏览器&#xff0c;可以在…

亚信科技基于 Apache SeaTunnel 的二次开发应用实践

亚信科技在Apache SeaTunnel的实践分享 自我介绍 各位同学好&#xff0c;很荣幸通过Apache SeaTunnel社区和大家进行分享交流。我是来自亚信科技的潘志宏&#xff0c;主要负责公司内部数据中台产品的开发。 本次分享的主题是Apache SeaTunnel在亚信科技的集成实践&#xff0c…

简单客服聊天数据库设计

1、主要功能包含&#xff1a; 收发消息&#xff0c;聊天列表&#xff0c;未读消息&#xff0c;修改为已读消息&#xff0c;双方对话内容记录。2、表结构&#xff1a; bds_user_message&#xff08;聊天消息内容表&#xff09; 3、业务代码没有特殊处理&#xff0c;就只放几…

如何使用可道云结合内网穿透工具实现远程访问打造私人云盘

文章目录 1.前言2. Kodcloud网站搭建2.1. Kodcloud下载和安装2.2 Kodcloud网页测试 3. cpolar内网穿透的安装和注册4. 本地网页发布4.1 Cpolar云端设置4.2 Cpolar本地设置 5. 公网访问测试6.结语 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易…

kubernetes部署rocketmq集群

一、添加rocketmq仓库 # helm repo add rocketmq https://helm-charts.itboon.top/rocketmq# helm repo up# helm search repo rocketmq# helm pull rocketmq/rocketmq-cluster --version 11.4.0# tar -zxf rocketmq-cluster-11.4.0.tgz 二、修改value值 这里面需要根据自己的…

使用mybatis的statementHander拦截器监控表和字段并发送钉钉消息

新建mybatis的statementHander拦截器拦截器 类 面试题&#xff1a; 2.实现 解析Sql时引入JSqlParser JSqlParser 是一个 SQL 语句解析器。 它将 SQL转换为可遍历的 Java 类层次结构。 <dependency><groupId>com.github.jsqlparser</groupId><artifac…

生物素-十一聚乙二醇-沙利度胺;Biotin-PEG11-Thalidomide

Biotin-PEG11-Thalidomide&#xff0c;即生物素-十一聚乙二醇-沙利度胺&#xff0c;是一种结合了生物素、十一聚乙二醇&#xff08;PEG11&#xff09;和沙利度胺的复杂化合物。以下是对该化合物的详细分析&#xff1a; 一、组成成分及特性 生物素&#xff08;Biotin&#xff09…

消费者画像有哪些类型?详解消费者画像绘制流程!

随着传统营销模式的局限性日益凸显&#xff0c;品牌商和企业逐渐认识到&#xff0c;精准定位目标受众对于资源的有效利用至关重要。在新零售时代&#xff0c;大数据技术的应用为营销策略提供了新的视角和工具。通过细致入微的消费者数据分析&#xff0c;企业能够构建起详尽的消…

Day02-ES集群常见术语,索引管理,文档管理,IK分词器,数据类型映射及kibana环境安装

Day02-ES集群常见术语&#xff0c;索引管理&#xff0c;文档管理&#xff0c;IK分词器&#xff0c;数据类型映射及kibana环境安装 1、昨日内容回顾2、今日内容预告3、ES的常见术语4、索引管理4.1 查看索引4.2 创建索引4.3 修改索引4.4 删除索引4.5 索引别名4.6 关闭索引4.7 打开…

【Tomcat目录详解】关于Tomcat你还需要了解的详细内容

希望文章能给到你启发和灵感&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏 支持一下博主吧&#xff5e; 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、Tomcat的文件结构2.1 bin目录2.1.1 startup和shutdown2.1.2 Catalina2.1.3 serv…

我们水冷使制动电阻功率密度成倍增加-水冷电阻设计工厂

先进陶瓷 我们后来发现工业应用中对占用空间最小的水冷电阻器的工业需求&#xff0c;推出了适用于中压工业应用的水冷电阻器。它的特点是两块由具有特殊性能的先进陶瓷制成的板。 使用工业电驱动装置的一个重要好处是&#xff0c;可靠的再生和动态制动系统可以补充或取代传统…

Unity 中使用状态机模式来管理UI

1. 清晰的状态管理 状态机模式允许你以结构化的方式管理不同的UI状态。每个状态&#xff08;比如主菜单、设置菜单、游戏中界面等&#xff09;都有其独立的行为和属性&#xff0c;这使得管理复杂UI逻辑变得更加清晰和可维护。 2. 简化的状态切换 状态机模式可以简化不同UI状…

Javaweb11-Filter过滤器

Filter过滤器 1.Filter的基本概念&#xff1a; 在Java Servlet中&#xff0c;Filter接口是用来处理HttpServletRequest和HttpServletResponse的对象的过滤器。主要用途是在请求到达Servlet之前或者响应离开Servlet之前对请求或响应进行预处理或后处理。 2.Filter常见的API F…