简介
二分查找是一种很重要的算法,二分,意味着每次查找都是切分进行的,也就是数据量会成倍减少,达到log(n)的查找效率。不过二分要灵活应用不是很简单。
常见思路:设置左中右,判断值在哪个区间,然后调整新的左中右。
难点:判断值在哪个区间。
做法:我推荐从数据的排列方式和题目要求入手,有序的自然就好切入了,如果是无序的,自然要从要求切入,比如查找峰值,显然是从峰值存在的特征入手。
二分查找——第一个错误版本
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int l = 1;
int r = n;
int m = l + (r-l)/2;
while(l<=r){
if(isBadVersion(m)){//m如果错误了,结果肯定在l-m之间
if(m==1||!isBadVersion(m-1))//如果第一个版本就错了或者前一个版本对了,说明此处是错误的起点
return m;
r = m-1;
}else
l = m+1;
m = l + (r-l)/2;
}
return -1;
}
};
寻找峰值
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int l = 0;
int r = nums.size()-1;
int m = l + (r-l)/2;
if(nums.size()<1)
return -1;
if(nums.size()==1)
return 0;
if(nums[l]>nums[l+1])
return 0;
if(nums[r]>nums[r-1])
return r;
while(l<=r){
if(m==0)
return 1;
if(nums[m]>nums[m-1]&&nums[m]>nums[m+1])
return m;
if(nums[m]>nums[m-1])
l = m + 1;
else
r = m - 1;
m = l + (r-l)/2;
}
return m;
}
};