二分查找的边界问题是怎么产生的?

总结:二分查找的目标有两个,一个是左区件的右边界,一个是右区间的左边界

如何去理解二分的过程?

如果要查找的是左区间的右边界

可以将[l, r]理解一个集合,这个集合范围内的数都有可能是最后需要得到的目标值--左区间的右边界这个点

每次要做的事情就是去缩小(更新)这个集合,最终使得集合里只有一个元素,那个元素就是目标值

每一次用mid去找集合的中点,有一个大前提:结合的结构[需要的值的集合|不需要的值的集合]

为了方便理解这个集合,我们可以理解为假设你有一个飞镖(也就是mid),有一个靶子(就是这个数组),靶子有内环(边界点所在的区间或者说集合)和外环(我们要找的集合的补集),靶子有一个中心点(内环的边界,也就是需要找到左区间的右边界)。

mid的位置有两种情况:落在左区间 里或者落在右区间

  • 如果落在了左区间,相当与告诉你了一个信息:从这个地方包括这个地方(mid所在的索引)往后([mid, r]),可能会发现右边界。与之对应的信息是右边界绝对不在mid左边的集合内([l, mid-1]),所以左边的集合([l, mid-1])就可以被删掉了,要实现这个操作只需要让下一次判断的集合是[mid, r]就i可以了,等价于l=mid
  • 如果落在了右区间,相当于告诉了你:这个点往右(包括这个点)都不是我要的区间,需要被删掉。那就直接令l = mid-1,删除集合中绝对不是答案的那一坨,也就是右边那一坨
  • 这样不断的往复删除确定的无用集合,最后就可以得到一个目标集合。

对于查找到是右区间的左边界也是一个原理。

mid的计算是左偏还是右偏怎么去判断?

关于mid的计算方式mid=i+j >> 1还是(mid=i+j>>1) + 1,个人有一种比较好理解的方法:

同样分两种情况:

  1. 找左区间右边界
  2. 找右区间左边界

左区间右边界

  • 首先要明白产生边界问题的原因在哪里

奇数个集合的时候,对于两者mid都是指向中间元素,但是如果集合个数是偶数,他们的中点是谁?很显然,两者都不是中点(1 中点是我 2中的那是12中间的文字吧)。

所以要么去文字左边的1为中点,要么取文字右边的2为中点。这样一来这个中点其实就不是真正意义上的中点了。

首先说结论,取右边界需要右偏,我们来分析一下:

对于集合很大的时候,是没有问题的,边界问题只会发生在集合很小的时候,所以只有拿出一个很小的集合,一个快被处理结束的集合,才能够知道为啥左偏会进入死循环,为啥不能用它这个问题。

所以直接去分析两个元素时有哪些情况:(O表示的是左区间右边界所在的集合,X表示待删除的集合)

  • [O, O]
  • [X, X]
  • [O, X]
  • [X, O]

其中,[X, O]这种情况不可能存在,因为左区间的相对顺序一定在左边

左边界l是指向第一个元素的,右边界r是指向第二个元素的

mid如果找到目标元素并不会剔除,并不会缩小范围,所以这个时候想要缩小范围就需要mid起作用了

对于[O, O]二分查找如果左偏会去看第一个元素,包含它,这没什么问题,只要我们的mid下一次去往右看就行了,但是问题就在于下一次mid看左边还是看右边是和左偏绑定在一起的,所以如果左偏,下一次mid还会看左边,如果右偏下一次mid还会看右边,但是我们需要看右边啊!所以只能够右偏了,这样遇到这种情况mid也能继续向右看去。

同样的对于右区间左边界的判断也是如此

  • [O, O]

其实说白了就是,两个元素时,找右边界时遇到需要的元素l会直接落在mid上进行更新。

找左边界时, 遇到需要的元素,r会直接落在mid上进行更新,为了防止更新后继续重合。

  • 找右边界,mid下一次查找只能偏右更新,避开l防止死掉

  • 找左边界,mid下一次查找就只能偏左更新,避开r防止死掉

相关推荐
Themberfue4 分钟前
基础算法之双指针--Java实现(下)--LeetCode题解:有效三角形的个数-查找总价格为目标值的两个商品-三数之和-四数之和
java·开发语言·学习·算法·leetcode·双指针
陈序缘29 分钟前
LeetCode讲解篇之322. 零钱兑换
算法·leetcode·职场和发展
-$_$-32 分钟前
【LeetCode HOT 100】详细题解之二叉树篇
数据结构·算法·leetcode
大白飞飞34 分钟前
力扣203.移除链表元素
算法·leetcode·链表
学无止境\n1 小时前
[C语言]指针和数组
c语言·数据结构·算法
黄俊懿1 小时前
【深入理解SpringCloud微服务】手写实现各种限流算法——固定时间窗、滑动时间窗、令牌桶算法、漏桶算法
java·后端·算法·spring cloud·微服务·架构
新缸中之脑1 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
夜雨翦春韭1 小时前
【代码随想录Day29】贪心算法Part03
java·数据结构·算法·leetcode·贪心算法
Curry_Math2 小时前
Acwing 区间DP & 计数类DP
算法
Tisfy2 小时前
LeetCode 1928.规定时间内到达终点的最小花费:动态规划
算法·leetcode·动态规划·