mid可以写成1+l+(r-l)/2吗

mid可以写成1+l+(r-l)/2吗

听完死循环产生的原因我的第一反应是把mid改成1+l+(r-l)/2,当时是想着既然由于整数除法倾向取左那么我就将他向右直接+1这样就倾向于取右边,这样写用课程中的测试结果正常,mid可以写成1+l+(r-l)/2吗,会有一些可能出问题的地方吗?

正在回答

登陆购买课程后可参与讨论,去登陆

4回答
l + (r - l) / 2 + 1


可以避免死循环的问题,算法也是正确的,但是在一些情况下,不能平分。


比如 l = 2,r = 10,平分的话,mid 应该是 6。但是 2 + (10 - 2)/ 2 + 1 = 7.


不过因为肯定只是偏移 1 位,所以对整个算法的性能影响不大。


另外注意,这样写,不保证 mid 在 [l, r] 内。当 l == r 时,l + (r - l) / 2 + 1 = l + 1,在 [l, r] 外了。但是因为我们的这个算法在 l == r 时,已经退出循环了,所以这一点不影响。但在别的需要在 [l, r] 找中间一点的算法中,这一点可能会引入 bug。


继续加油!:)

假蛙工程师 2021-11-27 17:24:30
  • 直呼好家伙,我跟题主想得一模一样,并且觉得两种方式并没有什么区别。但是,又对它们是否存在细微的差别感到很好奇,因此点进来了。看了老师的解释,醍醐灌顶。


    老师的实现 mid = l + (r - l + 1) / 2; 语义上是符合“向上取整”的。


    取个例子,老师的加1, 相当于添加了一个不存在的元素,即(r + 1 - l) / 2,r + 1, 添加了一个不存在元素,这里假设为x,所以r 要像右边平移一个单位。


    一 、假设有三个元素


    10  20  30 


    mid 应该指向20


    老师的思想:

    10  20  30   x

     l                 r            

    mid 指向 20 和 30 的中间,然后向下取整,mid还是20,对奇数个元素没有影响。


    我们的思想【l + ( r - l ) / 2 + 1】:

    10 20 30

     l          r

    mid 指向20 ,然后再加1 ,mid就指向了30,三个元素中点成了最右边的第三个元素。


    二、同理,假设有一个元素

     

      10

    l      r

    中点应该是10

    老师的思想:

    10    x

     l       r

    mid 指向 10 和 x 的中间,然后向下取整,mid还是10



    三、 假设有两个元素(或者偶数个元素)


    10 20 

     l    r

    如果 l + ( r - l ) / 2 那么,这就是向下取整,mid指向10


    老师的思想:


    10 20 x

     l        r

    mid指向20,从效果上看,似乎是向上取整了。



    我们的思想

    10 20 

    mid 先指向10 后向后偏移一位,从效果上看也是向上取整了。


    综上所述:

    区间中有偶数个元素,的确,两种方式都可以达到效果,

    区间中有奇数个元素,我们的方式【l + ( r - l ) / 2 + 1】不能取到中间值。



    2021-11-27 17:24:43
假蛙工程师 2021-11-27 17:23:50

直呼好家伙,我跟题主想得一模一样,并且觉得两种方式并没有什么区别。但是,又对它们是否存在细微的差别感到很好奇,因此点进来了。看了老师的解释,醍醐灌顶。


老师的实现 mid = l + (r - l + 1) / 2; 语义上是符合“向上取整”的。


取个例子,老师的加1, 相当于添加了一个不存在的元素,即(r + 1 - l) / 2,r + 1, 添加了一个不存在元素,这里假设为x,所以r 要像右边平移一个单位。


一 、假设有三个元素


10  20  30 


mid 应该指向20


老师的思想:

10  20  30   x

 l                 r            

mid 指向 20 和 30 的中间,然后向下取整,mid还是20,对奇数个元素没有影响。


我们的思想【l + ( r - l ) / 2 + 1】:

10 20 30

 l          r

mid 指向20 ,然后再加1 ,mid就指向了30,三个元素中点成了最右边的第三个元素。


二、同理,假设有一个元素

 

  10

l      r

中点应该是10

老师的思想:

10    x

 l       r

mid 指向 10 和 x 的中间,然后向下取整,mid还是10



三、 假设有两个元素(或者偶数个元素)


10 20 

 l    r

如果 l + ( r - l ) / 2 那么,这就是向下取整,mid指向10


老师的思想:


10 20 x

 l        r

mid指向20,从效果上看,似乎是向上取整了。



我们的思想

10 20 

mid 先指向10 后向后偏移一位,从效果上看也是向上取整了。


综上所述:

区间中有偶数个元素,的确,两种方式都可以达到效果,

区间中有奇数个元素,我们的方式【l + ( r - l ) / 2 + 1】不能取到中间值。



  • 提问者 Wonwayshon #1

    感谢分享!

    2021-11-29 09:58:19
假蛙工程师 2021-11-27 17:23:30

直呼好家伙,我跟题主想得一模一样,并且觉得两种方式并没有什么区别。但是,又对它们是否存在细微的差别感到很好奇,因此点进来了。看了老师的解释,醍醐灌顶。


老师的实现 mid = l + (r - l + 1) / 2; 语义上是符合“向上取整”的。


取个例子,老师的加1, 相当于添加了一个不存在的元素,即(r + 1 - l) / 2,r + 1, 添加了一个不存在元素,这里假设为x,所以r 要像右边平移一个单位。


一 、假设有三个元素


10  20  30 


mid 应该指向20


老师的思想:

10  20  30   x

 l                 r            

mid 指向 20 和 30 的中间,然后向下取整,mid还是20,对奇数个元素没有影响。


我们的思想【l + ( r - l ) / 2 + 1】:

10 20 30

 l          r

mid 指向20 ,然后再加1 ,mid就指向了30,三个元素中点成了最右边的第三个元素。


二、同理,假设有一个元素

 

  10

l      r

中点应该是10

老师的思想:

10    x

 l       r

mid 指向 10 和 x 的中间,然后向下取整,mid还是10



三、 假设有两个元素(或者偶数个元素)


10 20 

 l    r

如果 l + ( r - l ) / 2 那么,这就是向下取整,mid指向10


老师的思想:


10 20 x

 l        r

mid指向20,从效果上看,似乎是向上取整了。



我们的思想

10 20 

mid 先指向10 后向后偏移一位,从效果上看也是向上取整了。


综上所述:

区间中有偶数个元素,的确,两种方式都可以达到效果,

区间中有奇数个元素,我们的方式【l + ( r - l ) / 2 + 1】不能取到中间值。


问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
算法与数据结构
  • 参与学习       2583    人
  • 解答问题       1082    个

慕课网算法名师Liuyubobobo,5年集大成之作 从0到工作5年,算法与数据结构系统解决方案

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师