В процессе проработки вопросов автор обнаружил, что некоторые грамматики и алгоритмы легко забыть, поэтому в этой серии заметок для прояснения вопросов мы хотим записать некоторые распространенные грамматики и алгоритмы для облегчения повторения и закрепления. Содержание этой серии обновлено. синхронно в соответствии с ходом чистки вопросов.
Введение
Двоичный поиск , также известный как бинарный поиск , представляет собой алгоритм поиска элемента в упорядоченной последовательности. Алгоритм основан на предпосылке упорядоченной последовательности, и каждый поиск может сократить диапазон поиска вдвое.
Основная идея
Возьмем в качестве примера восходящую последовательность чисел (отсортированную от наименьшего к наибольшему). Сначала найдите средний элемент Middle
массива , а затем сравните его с искомым целевым элементом Target . Если средний элемент Middle равен Target, поиск завершается , если средний элемент Middle меньше Target, то левый элемент будет только меньше Middle и не будет равен Target, то нам нужно найти только Target в правый элемент ; если средний элемент Middle больше Target, то нам нужно найти только Target в левом элементе .
сложность
Временная сложность: O(log n) , где n — длина массива.
Пространственная сложность: O(1) . Нам нужно только постоянное пространство для нескольких переменных.
вопрос
Учитывая отсортированный массив и целевое значение , найдите целевое значение в массиве и верните его индекс . Если целевое значение не существует в массиве, возвращает позицию, в которую оно будет вставлено по порядку .
код
#include<iostream>
#include<vector>
using namespace std;
int binary_search(vector<int>& nums, int target)
{
int n = nums.size();
int left = 0, right = n - 1, flag = n;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (target <= nums[mid]) {
flag = mid;
right = mid - 1;
}
else {
left = mid + 1;
}
}
return flag ; //返回索引或将被插入的位置
}
int main()
{
vector<int> nums={
1,3,5,6 };
int target = 3;
count << binary_search(nums, target) << endl;
return 0;
}
Примечание: влево + ((вправо - влево) >> 1) == (влево + вправо) /2
влево + вправо может превышать максимальное значение, которое может содержать базовый тип в некоторых случаях, и >> (двоичный сдвиг вправо) является быстрее, чем /, поэтому лучше использовать выражение слева.