笔者在刷题的过程中,发现部分语法和算法容易遗忘,因此本系列刷题笔记想要记录一些常用语法和算法,便于复习巩固,本系列内容根据刷题进度同步更新。
简介
二分查找,又称折半查找,是一种在有序数列中查找某一元素的算法。该算法建立在有序数列的前提下,每次查找可以缩减掉一半的搜索范围。
基本思路
以一个升序数列(从小到大排序)为例。
首先找到该数列的中间元素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;
}
注:left + ((right -left) >> 1) == (left + right) /2
left + right 在某种情况下可能会超过基本类型所能容纳的最大值,且 >> (二进制右移) 比 / 运算快,所以用左边的表达式更好一些。
版权声明:本文为weixin_44842318原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。