目录
前言
二分查找是是必学算法之一,蓝桥杯、acm等竞赛都大概率会出现,面试的时候也需要用到,所以我们要熟练掌握,下面让我们来深入了解二分查找的应用场景。
零、二分查找的概念
二分查找,也称为折半查找(Binary Search),是一种在 有序数组 中查找特定元素的搜索算法。 它的基本思想是将目标值与数组中间的元素进行比较,如果目标值小于中间元素,则在数组的左半部分继续查找,否则在右半部分查找,不断缩小搜索范围,直到找到目标值或确定目标值不存在为止。 二分查找的时间复杂度为 O (logn) ,即查找效率较高。
一、动态图解
二、经典例题
1、收索插入位置
(帅哥们这个蓝色字体可以点进去看原题)
1.1、解题思路
定义两个游标代表左区间(l)和右区间r的端点,然后找中间(mid)端点,如果该位置的值大于(a[mid]>=value)等于我们要找的值,那么将右端点压缩一半区间,将r=mid。反之,将r=mid。重复进行此次循环,循环条件为l<r,循环结束后只剩下l与r两个端点,因为a[r]>=value,所以只需要判断a[r]是否等于value即可,如果等于说明找到了,反之,没找到。
1.2、代码题解
class Solution {
bool isGreen(vector<int>&nums,int m,int t){
return nums[m]>=t;//判断nums[mid]的值是否大于等于要找的值
}
int bSearch(vector<int>& nums,int t){
int l=-1;
int r=nums.size();
while(l+1<r){
int mid=(l+r)/2;
if(isGreen(nums,mid,t)){
r=mid;
}
else l=mid;
}
return r;
}
public:
int searchInsert(vector<int>& nums, int target) {
return bSearch(nums,target);
}
};
2、二分查找
2.1、解题思路
这题和第一题一样就是用红绿灯标记法进行二分查找,相信前面的题目理解了,这题你也能胸有成竹的写出来。
2.2、代码题解
class Solution {
bool isGreen(vector<int>& nums,int m,int t){
return nums[m]>=t;
}
int bSearch(vector<int>& nums,int t){
int l=-1,r=nums.size();
while(l+1<r){
int mid=(l+r)/2;
if(isGreen(nums,mid,t))r=mid;
else l=mid;
}
return r;
}
public:
int search(vector<int>& nums, int target) {
int ret=bSearch(nums,target);
if(ret==nums.size())return -1;//r等于数组最右端说明所有值都比target小就找不到
if(nums[ret]!=target)return -1;//找到了大于等于target的值,但是不等于说明只有nums[ret]>target这种情况
return ret;
}
};
2、在排序数组中查找元素的第一个和最后一个位置
2.1、解题思路
这一题稍微有点难度,但是也不多,其实总体思路和前面两题都一样,就是多了一个条件,我们要找结束位置, 这个结束位置也就是找出大于等于目标值加一(target+1<=a[i])的最小下标r,然后r-1就是目标值的结束位置,这个要好好理解,我相信你能想出来。
2.2、代码题解
class Solution {
bool isGreen(vector<int>& nums, int m,int t){
return nums[m]>=t;
}
int bSearch(vector<int>& nums, int t){
int l=-1,r=nums.size();
while(l+1<r){
int mid=(l+r)/2;
if(isGreen(nums,mid,t))r=mid;
else l=mid;
}
return r;
}
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int>ans;
int idx1=bSearch(nums,target);
int idx2=bSearch(nums,target+1);
if(idx1==nums.size())return {-1,-1};
if(nums[idx1]!=target)return {-1,-1};
ans.push_back(idx1);
ans.push_back(idx2-1);
return ans;
}
};
都看到这里了,希望帅哥你能点赞关注多多支持一下,非常感谢。