首页 > 编程语言 >数据结构与算法---二分法 超详细解,保证你能看懂!!!!!

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!

时间:2022-10-27 20:06:16浏览次数:56  
标签:--- guess 指向 mid 二分法 能看懂 例题 我们


二分法不难,看完这篇文章,你必懂。

假如我们遇到了一道算法题,要求我们从数组A=[a,b,c,d,e] 里找到d,那通常我们会逐个遍历,遍历a,b,c,d一共需要对比4个数字才能找到d。

那如果使用二分法呢?如何使用二分法?

1.首先我们设置两个指针指向该数组的开头和结尾,

L指向开头,R指向结尾。

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_python

2. 我们找到两个指针的中间点mid,(此时L为1,R为5,通常情况下mid=(L+R)/2)=3

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_算法_02


3. 对比mid和我们所需要找的数之间的大小,我们要找的是D显然C<D,此时将L挪到mid的位置,然后算出新的mid。

(如果本题要找的是B,同理,mid所指向的C大于B,则将R放到mid的位置然后算出新的mid。)

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_函数返回_03


4. 重复上面的步骤继续对比mid所指向的数是不是等于我们要找的数。mid=D 是我们要找的数,结束。

5. 如果L都移动到R的右边了还没找到我们要的数,则可以判断,这堆数里没有我们要找的数。

上面就是二分法的基本思想,可以看到,如果使用普通方法找D我们需要对比A,B,C,D 四次,而使用二分法我们只对比了C和D 2次就找到了。

杂谈:
关于二分法还有相当多的变种,现在讲必然会乱到炸。比如移动的时候不是直接将R或者L放到mid 而是放到mid+1 或者mid-1。。而在L和R的设置上也有开闭区间等多种,在mid计算上也有向下向上取整的问题。

这些都不要管!!!!!!!!!!!!!!!!!!

只需要懂得上面的思想,然后拿题去一点一点做去试,一开始必然都是错误,返回去继续想一遍流程,再改,这些都会融会贯通的。

怎么去试呢?

下面我用一个例题,让你从此以后彻底掌握二分法。(其他算法那也可以用此方法融会贯通)。

例题:

这里使用的例题:leetcode 374题。
题目给了一堆数共n个。 其中只有一个是正确的数,你要猜一下这个正确的数是几。
只不过你猜的这个数要通过一个函数去判断你猜的对不对。
如果函数返回了 1 说明正确的数比你猜的数要大。
如果函数返回了 -1 说明正确的数比你猜的数要小。
如果返回了0 说明你猜对了。

那么按照上面的算法思想写一下代码。
设置L和R指向头和尾 那就是

L = 1
R =

如果L一直在R左边,那就一直算mid。

while l < r:
mid = (l+r) // 2

每次算出来的新mid,调用函数看他是不是正确的数。

if guess(mid) == 0:
print(‘这是正确的数’)
elif guess(mid) == -1:
r = mid
elif guess(mid) == 1:
l =

我们吧上面的代码拼接起来(别忘了print改成return)

拿去leetcode跑一遍测试用例发现,当n=2,所要找的数=2时。

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_算法_04


超时了。。。。。。。。

超时的原因肯定是while没有出来。于是我们将 n=2 ,正确的数=2带入到上面的错误程序中。

首先
L = 1
R = 2
算出mid =(L+R)/ 2 = 1

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_数据结构_05


此时发现L和mid都指向1,显然我们要找的2是比1要大的,所以调用的guess函数返回了 1 执行代码:

elif guess(mid) == 1:
l =

本来mid和L就已经指向同一位置了。执行了这段代码等于什么也没干,就这样一直死循环在while里导致程序运行超时。

这时候怎么办呢,我们要找的明显是2。

此时使用二分法的变种(实际就是根据题的需要改变二分法的写法).

我们可以将 L = mid 改为 L = mid +1 这样L就会指向2。
改动代码:

elif guess(mid) == 1:
l = mid +1

还是这个图, 当函数guess返回1的时候 L = mid L和mid都是指向1.程序死循环,而我们改成了 L = mid + 1 ,则此时L会指向 R所指的位置。

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_算法_06


数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_python_07


此时进入下一次while循环发现L<R 已经不满足无法在进入循环,程序失败。所以将循环退出条件改为 L <= R。进入循环,计算新的mid=2.判断函数返回0,程序正确结束。拿去leetcode进行测试。

数据结构与算法---二分法 超详细解,保证你能看懂!!!!!_python_08


测试通过。掌握基本思想,通过例题逐步调试写出正确二分法的变种,更利于学习算法思想。

第一次这样手写讲解算法,如果有不懂的地方或者讲解有错误,留言给我,互相进步。


标签:---,guess,指向,mid,二分法,能看懂,例题,我们
From: https://blog.51cto.com/u_15849381/5801741

相关文章