int search(const vector<int>& nums, int target) {
if (nums.empty()) return -1;
int l = 0;
int r = nums.size(); // element after the last
while (l + 1 < r) {
int m = l + (r - l) / 2; // rather than `(l + r) / 2`, to avoid int overflow
if (a[m] > target) {
r = m;
} else {
l = m;
}
}
return nums[l] == target ? l : -1;
}
Замечания:
- $r$ указывает на элемент после последнего, что позволяет избежать $\pm 1$ при обновлении $l$ и $r$.
- Если писать ($l$ + $r$) / 2, то могут придраться, что $l + r$ может вылезти за границы типа
int. - Данный код находит самый правый элемент, равный $target$. Если хочется искать самый левый, то считаем, что $a[-1] = -\infty$ и $a[l]$ всегда меньше $target$. Конкретнее:
...
int l = -1;
int r = nums.size() - 1;
...
if (a[m] < target) {
l = m;
} else {
r = m;
}
...
return nums[r] == target ? r : -1;
...