#algorithm *Бинарный поиск*
Пусть есть некое условие p(i) и отрезок поиска [L, R].
Условие p монотонно - то есть, найдется такое x что оно выполняется для всех чисел <= x и не выполняется для чисел > x.
*Задача*: найти значение x.
*Решение*: будем считать что p(L-1) = true и p(R+1) = false.
Установим в начале l=L-1 и r=R+1 и будем поддерживать инвариант p(l)=true и p(r)=false внутри цикла.
int binarySearch(int L, int R, function<bool(int)> p) {
int l = L-1, r = R+1;
while (l + 1 < r) { // итерируемся пока l и r не будут соседними числами
int mid = (l + r) / 2; // если l и r не соседи то mid != l, mid != r
if (p(mid)) {
l = mid;
} else {
r = mid;
}
}
return l; // для i <= l p(i) == true, для i > l (i >= r) p(i) == false
}
*Примеры использования*:
_Дан отсортированный массив a = [a0, a1, .., an], все элементы различны. Найти в нем элемент k._
p(i) = a[i] <= k; L=0; R=n. На выходе получим максимальный индекс x такой, что a[x] <= k. Если k есть в массиве то a[x] == k.
_Дан массив a = [a0 > a1 > .. > an < b1 < b2 < .. < bm]. Найти индекс минимального элемента (an).
p(i) = a[i] < a[i+1]; L=0; R=len(a)-1.
На выходе получим максимальный индекс x такой, что a[x] < a[x+1] > a[x+2].