数组如下:
[5,7,7,8,8,10]
问题:
返回有序数组中第一个>=8的数的位置,如果所有数都<8,返回数组长度
暴力做法:
遍历每个数, 询问它是否>=8 ?显然时间复杂度是O(n)
高效做法:
L和R分别指向询问的左右边界,即闭区间[L,R],M指向当前正在询问的数 (L=0, R=n-1)
5 7 7 8 8 10
L M R
观察上图我们很容易得出以下两个结论:
- 如果当前数是小于8, 由于数组是有序的, 那么当前数和当前数左边的所有数, 都是<8的
- 如果当前数是大于等于8, 由于数组是有序的, 那么当前数和当前数右边的所有数, 都是>=8的
如果当前数组长度是偶数的话,中间那个数的下标为(L+R)/2,
由于C++/JAVA中"/"是下取整的,所以此时的中位数是中间靠左的那个数
如果当前数组长度是奇数的话,中间那个数的下标为(L+R)/2,此时就是正中间的那个数
第二次查询->将L更新为M+1的位置
5 7 7 8 8 10
L M R
对于为啥不能将L更新为M?
这是因为我们每时每刻都是在闭区间上进行处理的,如果把L改成M,那就是左开右闭区间了.
当数组中只有一个元素时,
8
L,R
你把R更新成M,那不就死循环了吗
因为arr[4]=8>=8,所以继续执行第三次查询
第三次查询->将R更新M-1
5 7 7 8 8 10
LR
arr((L+R)/2)>=8

最低0.47元/天 解锁文章
2845

被折叠的 条评论
为什么被折叠?



