mid可以写成1+l+(r-l)/2吗
听完死循环产生的原因我的第一反应是把mid改成1+l+(r-l)/2,当时是想着既然由于整数除法倾向取左那么我就将他向右直接+1这样就倾向于取右边,这样写用课程中的测试结果正常,mid可以写成1+l+(r-l)/2吗,会有一些可能出问题的地方吗?
正在回答
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。
继续加油!:)
直呼好家伙,我跟题主想得一模一样,并且觉得两种方式并没有什么区别。但是,又对它们是否存在细微的差别感到很好奇,因此点进来了。看了老师的解释,醍醐灌顶。
老师的实现 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】不能取到中间值。
直呼好家伙,我跟题主想得一模一样,并且觉得两种方式并没有什么区别。但是,又对它们是否存在细微的差别感到很好奇,因此点进来了。看了老师的解释,醍醐灌顶。
老师的实现 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 星