Полуинтервал
left, right := 0, len(nums)
for left < right {
mid := left + (right-left)/2
}
[left, right) уменьшает число особых случаев.
Ищи первую позицию, где монотонный предикат становится истинным.
Минимальный синтаксис, который понадобится в решении.
left, right := 0, len(nums)
for left < right {
mid := left + (right-left)/2
}
[left, right) уменьшает число особых случаев.
i := sort.Search(len(nums), func(i int) bool {
return nums[i] >= target
})
sort.Search реализует поиск первой true-позиции.
Три идиоматичных решения на Go с оценкой времени и памяти.
Первая позиция со значением не меньше target.
O(log n) time · O(1) spacefunc lowerBound(nums []int, target int) int {
left, right := 0, len(nums)
for left < right {
mid := left + (right-left)/2
if nums[mid] < target { left = mid+1 } else { right = mid }
}
return left
}
Бинарный поиск по ответу.
O(n log maxPile) time · O(1) spacefunc minEatingSpeed(piles []int, hours int) int {
left, right := 1, slices.Max(piles)
for left < right {
speed := left + (right-left)/2
used := 0
for _, pile := range piles { used += (pile+speed-1)/speed }
if used <= hours { right = speed } else { left = speed+1 }
}
return left
}
Lower bound одновременно находит элемент и позицию для его вставки.
O(log n) time · O(1) spacefunc searchInsert(nums []int, target int) int {
left, right := 0, len(nums)
for left < right {
mid := left + (right-left)/2
if nums[mid] < target { left = mid+1 } else { right = mid }
}
return left
}