二分查找
算法思想
前提序列已经排好序了,每次计算中间值,根据中间结果确定下次选择左右区间的哪个区间,逐渐逼近最终结果,每次缩小一半的范围,因此二分的时间复杂度为O( logn )。
类别
较常用的为左闭右闭和左闭右开两种,当存在重复元素时涉及到查找第一个和最后一个符合条件的,下面分别进行介绍。
左闭右闭
int left = 0, right = nums.size() - 1;
查找第一个:
等于target时向左收缩,即等于target时需要right = mid - 1;
int binSearch(vector<int> nums, int target)
{
int left = 0, right = nums.size() - 1;
while (left <= right)
{
int mid = left + ((right - left) >> 1);//移位更快
if(target <= nums[mid])
right = mid - 1;
else
left = mid + 1;
}
return left;
}
查找最后一个:
等于target时向右收缩,跳出循环时left = mid + 1,mid 为最后一个元素,所以left–;或者返回right。
int binSearch(vector<int> nums, int target)
{
int left = 0, right = nums.size() - 1;
while (left <= right)
{
int mid = left + ((right - left) >> 1);//移位更快
if(target < nums[mid])
right = mid - 1;
else
left = mid + 1;
}
return left--;
}
左闭右开
int left = 0, right = nums.size() ;
查找第一个:
等于target时向左收缩
int binSearch(vector<int> nums, int target)
{
int left = 0, right = nums.size();
while (left < right)
{
int mid = left + ((right - left) >> 1);//移位更快
if(target <= nums[mid])
right = mid;
else
left = mid + 1;
}
return left;
}
查找最后一个:
等于target时向右收缩,跳出循环时left = mid + 1,mid 为最后一个元素,所以left–;或者返回right。
int binSearch(vector<int> nums, int target)
{
int left = 0, right = nums.size();
while (left < right)
{
int mid = left + ((right - left) >> 1);//移位更快
if(target < nums[mid])
right = mid;
else
left = mid + 1;
}
return left--;
}