题目大意:
有一个数列从[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;
}
};

本文探讨了在一个特殊形态的数列中,如何利用二分查找算法以对数时间复杂度确定目标值的存在性。首先,需定位数列转折点,随后在两个单调递增子序列中分别应用lower_bound函数。文章提供了详细的算法思路与C++实现代码。

被折叠的 条评论
为什么被折叠?



