1、

分析:a、x<t---->left = mid+1
b、x>t------>right = mid -1
c、x=t----->返回结果
细节问题:a、循环结束的条件
left<right
b、时间复杂度logN
cpp
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0,right=nums.size()-1;
while(left<=right)
{
int mid = left+(right-left)/2;
if(nums[mid]<target)
left=mid+1;
else if(nums[mid]>target)
right=mid-1;
else
return mid;
}
return -1;
}
};
那么就可以总结模板
cpp
while(left<=right)
{
int mid = left+(right-left)/2;
if(...)
left=mid+1;
else if(...)
right=mid-1;
else
return ...;
}
注意二段性
2、
一、查找区间的左端点
根据二段性
1>x<t---->left = mid+1----->[left,right]
2>x>=t------>right = mid------>[left,right]
这就是本题思路,但是重点不在这里
细节处理:1>循环条件(left<right)
left<=right 大错特错
分析:a、有结果 b、全大于t c、全小于t
相等时,就是最终结果,无需判断,最坑人的就是,只要判断就会死循环,求中间值依旧是ret,ret不会移动,命中第2>条件,一直循环
2>求中点操作
left+(right-left)/2
二、查找右端点
1>x<t---->left = mid----->[left,right]
2>x>=t------>right = mid-1------>[left,right]
细节问题同上
cpp
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0)
return {-1,1};
int begin =0;
int left=0,right = nums.size()-1;
while(left<right)
{
int mid = left+(right-left)/2;
if(nums[mid]<target)
left=mid+1;
else
right=mid;
}
if(nums[left]!=target)
return {-1,1};
else
begin left;
int left=0,right=nums.size()-1;
while(left<right)
{
int mid = left +(right-left+1)/2;
if(nums[mid]<=target)
left=mid;
else
right = mid-1;
}
return {begin,right};
}
};
查找区间左端点的模板
cpp
while(left<right)
{
int mid = left+(right-left)/2;
if(...)
left=mid+1;
else
right=mid;
}
查找区间右端点的模板
cpp
while(left<right)
{
int mid = left+(right-left+1)/2;
if(...)
left=mid;
else
right=mid-1;
}
小技巧:当下面出现-1的时候,上面就+1
以上就是二分查找的模型,再用几个例题加深理解
3、
cpp
class Solution {
public:
int mySqrt(int x) {
if(x<1)
return 0;
int left = 1,right=x;
while(left<right)
{
int mid = left+(right-left+1)/2;
if(mid*mid<=x)
left=mid;
else
right= mid-1;
}
return left;
}
};
4、
cpp
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int left = 1,right=arr.size()-2;
while(left<right)
{
int mid =left+(right-left+1)/2;
if(arr[mid]>arr[mid-1])
left=mid;
else
right=mid-1;
}
return left;
}
};