题目大意:
有一个数列从[1,i] 单调递增,a[i+1]<a[1],然后[i+1,n]单调递增,现在问我们能不能以log的复杂度找到数列中是否存在某个数。
解题思路:
很显然,我们需要先找出i+1的坐标,然后使用两次lower_bound。那么我们怎么找到i+1的下标呢?这里有点像零点定理,每次我们找到中点m,假如中点的值大于a[1]的值,证明i+1在m的右边,否则i+1在m的右边,通过这样来找到结果!由于每次可以 以剩余距离的1/2来跳跃,所以总的复杂度在log。另外,这个二分有点不同于我们以前的划分为true,true,true,false,false或者 false,false,false,true,true的二分,所以写起来会有一点区别。
各种二分的写法:https://www.geeksforgeeks.org/the-ubiquitous-binary-search-set-1/
typedef long long ll;
class Solution {
public:
int search(vector<int>& nums, int target) {
ll x = 0;
ll y = nums.size();
if(y == 1){
if(target==nums[0])return 0;
else return -1;
}
int sz = nums.size();
while(x<y){
ll m = x+(y-x)/2;
if(nums[m]>=nums[0])x = m+1;
else y = m;
}
int pos = lower_bound(nums.begin(),next(nums.begin(),x),target)-nums.begin();
ll ret = -1;
if(pos<sz && nums[pos] == target)ret = pos;
int pos2 = lower_bound(next(nums.begin(),x),nums.end(),target ) - nums.begin();
if(pos2<sz && nums[pos2] == target )ret = pos2;
return ret;
}
};