关于二分法的一些问题

 我来答
舒适还明净的海鸥i
2022-06-03 · TA获得超过1.7万个赞
知道小有建树答主
回答量:380
采纳率:0%
帮助的人:69.4万
展开全部

以搜索区间为[0, len -1]为例子
左中位数下标数: (0 + len - 1) >>> 1
右中位数下标数: (0 + len - 1 + 1) >>> 1
左中位数为第k个: (len + 1) >>> 1
右中位数为第k个: (len + 1 >>> 1) + 1
其实,我们如果明白左中位数为第k个的公式是怎么得出来的,其他的就也都明白了。

既然我们能够计算出左中位数为第k个,那我们如果想计算下标数,只需k - 1即可,即
((len + 1) >>> 1) - 1 -> (len - 1) >>> 1

其实以上说的并不是很容易理解记住,我们在计算中位数的时候可以先尝试举几个例子,然后再写公式。我是通过记住下标的公式,求个数的时候加一即可。

有几点需要注意

可能你会好奇,为什么要根据边界更新来选择中位数,为什么找第一个target和最后一个target可以通过不同的模版实现,下面我们就讲一下这个问题。

二分法的本质是对区间进行操作,每一次查找去掉(一半)无用的区间
如果我们想找到第一个target, 那么我们就应该不断缩小右侧,同时保证target始终在区间中。

我们分开讲这两个过程:缩小、保证

如果想找最后一个target,也是相同的原理,可以自己分析一下

到这里,我们就讲完了为什么找第一个target和最后一个target可以通过不同的模版实现,下面我们讲一下为什么要根据边界更新来选择中位数。

我还闷还是一个找第一个target为例

通过以上,我们可以概括出一句话 左边界负责找到满足条件的范围,右边界负责收缩

我们采取反证法:如果取右中位数,那么考虑只剩两个元素的时候。如果nums[mid]满足条件,那么自然有right=mid,而因为是右中位数,所以right就是mid。显然,此时无法收缩了(所以模版要求这么做 谁=mid + 1就应该用哪个中位数)。
其内在原理是,left和right总是一个负责排除,一个负责收缩。
举个例子,当我们使用left去排除,即left = mid + 1, 那么right必然是收缩 right = mid,这时我们使用左中位数可以保证不管是排除还是收缩,区间都会变小(排除不用说了,肯定会变小;收缩的话至少也会将右中位数收缩掉)。反之,如果使用右中位数,那么收缩的时候区间可能不会变小(即上面说的只剩两个元素的情况)。

所以我们才选择使用左中位数,因为这样右边界才总能收缩到第一个满足条件的元素

现在再来我们试想 即使我们一开始找到的是一个大于target的数字 是不是边界不断收缩 最终找到的还是第一个满足条件的元素。

下面是我总结的一些题目要求及对应的解法

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式