方法一是线段树,查找区间最值
struct segTree{
int l,r;
int v;
int m;
};
void build(segTree tree[],int index,int l,int r,vector<int>& nums)
{
tree[index].l=l;
tree[index].r=r;
if(l==r)
{
tree[index].v=nums[l];
tree[index].m=nums[l];
return;
}
int mid=(l+r)>>1;
build(tree,index<<1,l,mid,nums);
build(tree,(index<<1)+1,mid+1,r,nums);
tree[index].v=max(tree[index<<1].v,tree[(index<<1)+1].v);
tree[index].m=min(tree[index<<1].m,tree[(index<<1)+1].m);
}
int searchV(segTree tree[],int index,int l,int r)
{
if(tree[index].l>r||tree[index].r<l)
return -1;
if(tree[index].l==l&&tree[index].r==r)
return tree[index].v;
int mid=(tree[index].l+tree[index].r)>>1;
if(r<=mid)
return searchV(tree,index<<1,l,r);
if(l>=mid+1)
return searchV(tree,(index<<1)+1,l,r);
int left=searchV(tree,index<<1,l,mid);
int right=searchV(tree,(index<<1)+1,mid+1,r);
return max(left,right);
}
int searchM(segTree tree[],int index,int l,int r)
{
if(tree[index].l>r||tree[index].r<l)
return -1;
if(tree[index].l==l&&tree[index].r==r)
return tree[index].m;
int mid=(tree[index].l+tree[index].r)>>1;
if(r<=mid)
return searchM(tree,index<<1,l,r);
if(l>=mid+1)
return searchM(tree,(index<<1)+1,l,r);
int left=searchM(tree,index<<1,l,mid);
int right=searchM(tree,(index<<1)+1,mid+1,r);
return min(left,right);
}
class Solution {
public:
bool search(vector<int>& nums, int target) {
int n=nums.size();
if(n==0)
return false;
int l=0,r=n-1;
segTree root[4*n];
build(root,1,0,n-1,nums);
while(l<=r)
{
int mid=(l+r)>>1;
if(target==nums[mid])
return true;
else if(target>nums[mid])
{
int h=searchV(root,1,mid+1,r);
if(target<=h)
l=mid+1;
else
r=mid-1;
}
else
{
int h=searchM(root,1,l,mid);
if(h<=target)
r=mid-1;
else
l=mid+1;
}
}
return false;
}
};
方法二:二分,若遇到中间值和左边值相同,可以控制右指针+1;
class Solution {
public:
bool search(vector<int>& nums, int target) {
int n=nums.size();
if(n==0)
return false;
int l=0,r=n-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(target==nums[mid])
return true;
if(nums[mid]>nums[l])
{
if(target<nums[mid]&&target>=nums[l])
r=mid-1;
else
l=mid+1;
}
else if(nums[mid]<nums[l])
{
if(target>nums[mid]&&target<=nums[r])
l=mid+1;
else
r=mid-1;
}
else
l++;
}
return false;
}
};