二分查找 红蓝染色法
查找有序数组中第一个>=8的数的位置,如果数据全部<8,则返回数组长度。
查找反转有序数组(例如 [3,4,5,1,2])中最小数的位置。
暴力做法:依次遍历数组中每个元素
暴力做法没有利用到数组的有序性
高效做法:两个指针L、R,分别指向左右边界(即,闭区间[L,R]),M指向正在询问的数。当M<8则是false(红色);当M>=8则是true(蓝色)
第一次迭代:
L,R := 0,n-1 // L为左边界;R为右边界
M := (L+R)/2 // M取中间值偏左(L+R可能存在溢出问题,)
compare(M, 8)
第二次迭代:(M<8, [0:M]区间的元素全部排除)
L,R := M+1, n-1 // L必须为M+1,而非M;否则当数组只有一个元素时,会陷入死循环。
M :=
第三次迭代: (M>=8, [M:n-1]区间的元素全部排除)
L,R := M+1, m-1
出口(关键)
循环不变量:
最终[0:L-1]一定小于8; [r+1: n-1]一定 >=8
根据循环不变量,R+1是最终答案
循环结束后,R+1=L,所以答案也可以用L表示