【算法笔记】 二分查找与二分答案入门超详细版,一篇给你讲懂

算法笔记 —— 二分入门

二分其实真挺重要的,因为他的应用范围比较广。竞赛中,许多知识也是由二分变出来的;甚至生活中,你也可以用二分解决一些看似比较难的问题,惊呆你的小伙伴😮😮😮

引入(大佬请直接跳到下一个环节)

猜数你们应该都玩过吧,你猜一个数,我会回答“大了”,“小了”或”猜出来了“。假设猜数的范围为1~100,我们需要尽可能地用最小的次数来猜出那个数,请问我们需要几次?

这个问题十分好想,每次我们都需要尽量缩小范围。如果你第一次猜20,30这些数,那万一那个数是100呢?就会导致下次猜数的范围偏大,所以有没有哪个数是可以固定住下一次猜数时的范围呢?有的有的。我们第一次直接取中间的50,这时不管那个要被猜的数在左在右,我们都可以缩小一半的范围。接下来继续找中间数维持平衡,直到最后一个值。

看一下需要猜几次,每次取数会缩小一半的范围,那就是 \(\frac{100}{2^x}\)\(2^7 = 128 > 100\) ,所以1~100范围内的只需猜7次。

这其实就是二分答案的一种基础题。

二分查找&二分答案

二分查找

概念:有序数组内找需求的已知的数的位置

假设这个数组是一段木头:

若没找到该数且当前数大了,把大于等于当前数的这半儿给砍了,判断没砍掉的;

若没找到该数且当前数小了,把小于等于当前数的这半儿给砍了,判断没砍掉的;

若找到该数,输出题目木要求需要输出的。

上面的这种思路不是唯一的,真实思路需根据实际题目调整

设被查找的有序数组={1,2,3,……100}(1到100,100个数),查找数为20

如图:
111

(不经意间展示画画水平)

给出代码

向左找,比如说问你某个值(那个值可以在一个数组中出现多次),在这个有序数组最先出现的位置

	while (l<=r){
		int mid=(l+r)/2;
		if (a[mid]==x) {cout <<mid; return 0;}
		else if (a[mid]>x) r=mid-1;
		else l=mid+1;
	}

向右找,比如说问你某个值(那个值可以在一个数组中出现多次),在这个有序数组最后出现的位置

	while (l<=r){
		int mid=(l+r)/2;
    if (a[mid]==x) cout <<mid;
		else if (a[mid]>x) l=mid+1;
		else r=mid-1;
	}

课后题目

二分答案

概念:在一段具有单调性的区间内,通过一堆判断条件找到满足条件的未知解。

首先我们重点聊聊这个单调性是什么。具有单调性的区间指的不一定是这个区间内的所有数有序,他指的是这段区间他的性质有序。就是说,这段区间内,若某一个值满足题目的判断条件,那么这个值左边的一大堆就也满足条件(看不懂没关系,直接看后面)

为什么必须要有单调性呢?如果这段区间不满足单调性,你判断到某个值不满足单调性,你有怎么可以说前面的所有值都不满足判断条件呢?

形象点,还是把这个区间看成一段木头。如果这段木头一节粗一节细,你判断到一节木头太细了(不满足条件),你能说他前面的也太细了(也不满足条件)吗,只有你先让这段木头从细到粗地排列(先把数组排序),你才可以判断到一节太细,把前面的全排了(前面全是比他更细的);一节太粗,把后面的全排了(后面全是比他更粗的)。

其实二分答案就相当于猜答案满不满足条件。用代码表示,就是先定 \(l,r\)\(l\) 表示当前下限, \(r\) 表示当前上限),取中间值,满足处理一遍,不满足又处理一遍(结合上面猜数字的引入来理解)。

给出代码:

向左找,比如说问最先满足条件的值是什么

	while (l<=r){
		int mid=(l+r)/2;
		if (chk(mid)) r=mid-1,ans=mid;
		else l=mid+1;
	}

向右找,比如说问最后满足条件的值是什么

	while (l<=r){
		int mid=(l+r)/2;
		if (chk(mid)) r=mid-1,ans=mid;
		else l=mid+1;
	}

课后题目

一些错误

有些人在取中间值时会出错,这是为什么?

因为 \(mid\) 溢出了,这时我们只需要把 \(mid=(l+r)/2\) 写成 \(mid=l+(r-l)/2\) 就行了。

\(while(l<=r)\)\(while(l<r)\) 有何区别?

\(while(l<=r)\) 是在检查所有数,判断目标是否存在。而 \(while(l<r)\) 则是在找最优解或边界。
如果你二分出错,不妨两者之间换一下试试。

课后练习

相信屏幕前聪明的你一定会了吧,来做做这个题单吧!

超简单题单

最后,给个赞吧😭😭😭

posted @ 2026-04-10 19:05  CJRcn  阅读(2)  评论(0)    收藏  举报