算法:二分查找(4种模板)
1.基本的二分查找(一)
条件:
[ left,right ]
左闭右闭
int binarySearch1(vector<int> nums,int target){
int left = 0;
int right = nums.size() - 1;//这个right是可以取到的
while(left <= right){//当left==right,区间[left, right]依然有效,所以用 <=
int mid = left + (right - left) / 2;
if(target < nums[mid]){
right = mid - 1;//下次寻找区间[left, mid - 1]
}else if(target > nums[mid]){
left = mid + 1;//下次寻找区间[mid - 1 , right]
}else if(target == nums[mid]){
return mid;
}
}
return -1;
}
2.基本的二分查找(二)
条件:
[ left , right)
:下标为right的值取不到
int binarySearch2(vector<int> nums,int target){
int left = 0;
int right = nums.size();//这个right是取不到的
while(left < right){ //right 取不到
int mid = left + (right - left)/2;
if(target < nums[mid]){
right = mid; //下次取不到 mid ,即下次的right 取不到
}else if(target > nums[mid]){
left = mid + 1;
}else if(target == nums[mid]){
return mid;
}
}
return -1;
}
3.基本的二分查找的两个模板的区别
区别总共有3点
第一种[left,right] | 第二种[left,right) | |
---|---|---|
1.初始 right | right = nums.size()-1; | right = nums.size(); |
2.while(条件) | left <= right; | left < right; |
3.target<nums[mid]后执行操作 | right = mid -1; | right = mid; |
4.左侧二分查找
左侧的二分查找:
在target
值在数组中有多个时,返回最左侧的target
值的下标
//基于基本的二分查找(二)的模板:左闭右开
int leftBinarySearch(vector<int> nums,int target){
int left = 0;
int right = nums.size();//注意点:左闭右开
while(left < right){//注意点
int mid = left + (right - left) / 2;
if(target < nums[mid]){
right = mid;//注意点
}else if(target > nums[mid]){
left = mid+1;
}else if(target == nums[mid]){
right = mid;//当找到第一个的时候我们继续寻找
}
}
return left;
}
5.右侧的二分查找
右侧的二分查找:
在target
值在数组中有多个时,返回最右侧的target
值的下标
//基于基本的二分查找(二)的模板:左闭右开
int RightBinarySearch(vector<int> nums,int target){
int left = 0;
int right = nums.size();
while(left < right){
int mid = left + (right - left) / 2;
if(target < nums[mid]){
right = mid-1;
}else if(target > nums[mid]){
left = mid;
}else if(target == nums[mid]){
left = mid;
}
}
return right;
6.左右侧二分查找总结:
左右侧二分查找的区别只有三个地方(注意函数返回值
)
目标值
小于nums[mid]
时:
- 左侧:
right = mid;
- 右侧:
right = mid-1;
目标值
大于nums[mid]
时:
- 左侧:
left = mid+1;
- 右侧:
left = mid;
目标值
等于nums[mid]
时:
- 左侧:
right = mid;
- 右侧:
left = mid;
左侧二分查找的思想就是不断收缩right
右侧二分查找的思想就是不断收缩left