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

先给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. 数的范围
标准的例题,做完应该就算会了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA之Debug的使用

自定义功能图表 功能说明 光标回到Debug行 执行到光标所在行 Force Step into Trace Current Stream Chain Reset Frame 重置方法入栈

C++基础学习笔记

1.命名空间(namespace) 1.什么是命名空间&命名空间的作用 1.在C/C中&#xff0c;变量、函数、类都是大量存在的&#xff0c;这些变量等的名称将都存在于全局作用域中&#xff0c;就会导致很多的命名冲突等。使用命名空间的目的就是对标识符的名称进行本地化&#xff0c;以…

Nginx七层(应用层)反向代理:UWSGI代理uwsgi_pass篇

Nginx七层&#xff08;应用层&#xff09;反向代理 UWSGI代理uwsgi_pass篇 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this a…

JavaSE学习笔记第二弹——对象和多态(下)

今天我们继续复习与JavaSE相关的知识&#xff0c;使用的编译器仍然是IDEA2022&#xff0c;大家伙使用eclipse或其他编译环境是一样的&#xff0c;都可以。 目录 数组 定义 一维数组 ​编辑 二维数组 多维数组 数组的遍历 for循环遍历 ​编辑 foreach遍历 封装、继承和…

网络编程的学习之udp

Udp编程过程 Sento不会阻塞 实现聊天室效果 上线 聊天 下线 服务端需要一个地址&#xff0c;去保留名字和ip地址 交互的时候发结构体 下面这个宏只能在c语言里使用 ser.sin_port htons(50000); 上面是端口号50000以上&#xff0c;两边要一样 这里是不要让udp发的太快&am…

Git命令常规操作

目录 常用操作示意图 文件的状态变化周期 1. 创建文件 2. 修改原有文件 3. 删除原有文件 没有添加到暂存区的数据直接 rm 删除即可&#xff1a; 对于添加到暂存区的数据 文件或目录&#xff1a; 4. 重命名暂存区数据 5. 查看历史记录 6. 还原历史数据 恢复过程的原…

C/C++ list模拟

模拟准备 避免和库冲突&#xff0c;自己定义一个命名空间 namespace yx {template<class T>struct ListNode{ListNode<T>* _next;ListNode<T>* _prev;T _data;};template<class T>class list{typedef ListNode<T> Node;public:private:Node* _…

低代码平台赋能企业全面数字化转型

引言&#xff1a;在当今这个日新月异的数字化时代&#xff0c;企业正面临着前所未有的机遇与挑战。为了保持竞争力并实现可持续发展&#xff0c;企业亟需进行全面的数字化转型。而低代码平台作为数字化转型的重要工具&#xff0c;正以其独特的优势赋能企业&#xff0c;推动其向…

Ollama完整教程:本地LLM管理、WebUI对话、Python/Java客户端API应用

老牛同学在前面有关大模型应用的文章中&#xff0c;多次使用了Ollama来管理和部署本地大模型&#xff08;包括&#xff1a;Qwen2、Llama3、Phi3、Gemma2等&#xff09;&#xff0c;但对Ollama这个非常方便管理本地大模型的软件的介绍却很少。 目前&#xff0c;清华和智谱 AI 联…

[计网初识1] TCP/UDP

学习内容 1.TCP建立链接的3次握手&#xff0c;断开连接的4次挥手 2.TCP报文段组成 内容 1.TCP 建立连接的3次握手? 假设主动方是客户端&#xff0c;被动方是服务端。 第一次 客户端给服务端发送 “hello,我是客户端” (TCP段中 SYN1) 第二次 服务端给客户端发送"我接…

汽车免拆诊断案例 | 2016款保时捷Macan车发动机故障灯异常点亮

故障现象  一辆2016款保时捷Macan车&#xff0c;搭载CYP发动机&#xff0c;累计行驶里程约为11.2万km。车主进厂反映&#xff0c;发动机故障灯异常点亮。 故障诊断  接车后试车&#xff0c;发动机怠速无明显异常&#xff0c;组合仪表上的发动机故障灯异常点亮。用故障检测仪…

AI in Finance 金融领域AI应用-基于DeepNLP AI App Store 真实用户评论打分和排名

AI在金融领域应用 AI in Finance 金融服务领域的AI应用和传统的金融智能应用不同。传统金融智能应用包括如风险评估 (Risk assessment), 风险管理&#xff08;Risk management), 欺诈检测 (Fraud Detection&#xff09;等等。 通用AI大模型和人工智能应用如ChatGPT&#xff0c…

echart5.5.1版本,倒三角柱状图

加载方法 initChart1(title, id, tag) {var myChart echarts5.init(this.$refs[id]);const _this this;var option {title:{text: title||"",show: title?true:false,top: 24,left: 24},grid:{left: 54,top: 74,bottom: 44,right: 30,},xAxis: {type: category,d…

1996-2023年各省农业总产值数据(无缺失)

1996-2023年各省农业总产值数据&#xff08;无缺失&#xff09; 1、时间&#xff1a;1996-2023年 2、来源&#xff1a;国家统计局、各省年鉴 3、指标&#xff1a;农业总产值 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释&#xff1a;农业总产值是…

CSS关于居中的问题

文章目录 1. 行内和块级元素自身相对父控件居中1.1. 块级元素相对父控件居中1.2. 行内元素相对于父控件居中 2. 实现单行文字垂直居中3. 子绝父相实现子元素的水平垂直居中3.1. 方案一3.1.1. 示例 3.2. 方案二3.2.1. 示例 3.3. 方案三(推荐)3.3.1. 示例 3.4. 方案四(了解一下) …

高盛开源的量化金融 Python 库

GS Quant GS Quant是用于量化金融的Python工具包&#xff0c;建立在世界上最强大的风险转移平台之一之上。旨在加速量化交易策略和风险管理解决方案的开发&#xff0c;凭借25年的全球市场经验精心打造。 它由高盛的定量开发人员&#xff08;定量&#xff09;创建和维护&#…

2970.力扣每日一题7/10 Java(暴力枚举)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 解题思路 解题方法 时间复杂度 空间复杂度 Code 解题思路 incre…

对智能的研究正在悄悄地诱发复杂取代科学

随着智能人工智能的发展&#xff0c;传统科学研究方法可能面临新的挑战或者被扩展。人工智能的发展带来了大数据分析、机器学习、深度学习等新的工具和方法&#xff0c;这些方法在处理复杂系统和大规模数据方面表现出色&#xff0c;使得科学研究变得更加多样化和复杂化。对智能…

stm32 开发板可以拿来做什么?

STM32开发板可以用来做许多不同的事情&#xff0c;具体取决于您的应用需求和编程能力。我收集归类了一份嵌入式学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言类教学&#xff0c;敲个22就可…

iMazing 3.0.3.1Mac中文破解版下载安装激活

今天&#xff0c;小编要分享的是Mac下一款可以帮助用户管理IOS设备的软件——iMazing&#xff0c;之前&#xff0c;小编也分享的过类似的软件&#xff0c;iMazing却有独特之处。小子这次带来的是3.0.3.1版本。 iMazing 3是一款iOS设备管理软件&#xff0c;该软件支持对基于iOS…