左移递减数列查找某一个数

微软(运算):
一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5}

是由{6,5,4,3,2,1}左移两位形成的,在这种数组中


#include<iostream>  
#include<cassert>  
#include<stack>  
using namespace std ;  
int FindNumberInLeftShiftSequence(int *A,int nLen,int expectedNum)  
{  
    assert(A!=NULL&&nLen>0);  
    int start=0;  
    int end=nLen-1;  
    while(start<=end)  
    {  
        int mid=start+((end-start)>>2);  
        if(expectedNum==A[mid])  
            return mid;  
        if (A[mid]<A[start])  
        {  
            if(expectedNum>A[mid])  
                end=mid-1;  
            else   
                start=mid+1;  
        }  
        else if(A[mid]>A[start])  
        {  
            if(expectedNum<A[mid])  
                start=mid+1;  
            else  
                end=mid-1;  
        }  
        else  
        {  
            for (int i=start;i<mid;i++)  
            {  
                if(A[i]==expectedNum)  
                    return i;  
            }  
            start=mid+1;  
        }  
    }  
    return -1;  
}  
int main()  
{  
    int A[]={6,5,4,3,2,1};  
    int nLen=sizeof(A)/sizeof(int);  
    cout<<FindNumberInLeftShiftSequence(A,nLen,0)<<endl;  
    int B[]={1,1,1,1,0,1};  
    int nLen2=sizeof(B)/sizeof(int);  
    cout<<FindNumberInLeftShiftSequence(B,nLen2,0);  
    return 1;  
}  


 

思路:在此序列不断二分的过程中,由于原序列是一个递减序列经过旋转得到的,将它从任何位置分开,都会得到两个序列,其中一个是递减序列,另一个可以通过一个递减序列通过旋转得到。这样在不断地二分查找时,我们处理的序列子片段要么就是一个旋转后递减序列,要么就是一个纯递减序列,而无论是前者还是后者,在继续分成两个片段时,至少有一个纯递减序列(可能两个都是,如果之前的序列片段就是纯递减序列的话)。这样我们可以保证能找到一个片段是纯递减序列(if(data[i]>=data[j])),然后判断我们要找的数是否在这个片段中(这是很直观的,if(data[i]<=num&&num<=data[j])),如果在则继续在此片段中查找,否则说明在另一个序列中,则递归在其中查找

代码:

#include<iostream>
using namespace std;
int bisearch(int a[],int left,int right,int num)
{
 if(a==NULL||right<0)  
        return -1;  

    if(left==right)  
    {  
        if(a[left]==num)  
            return left;  
        else  
            return -1;  
    }     

   int mid=(left+right)/2;
   if(a[mid]==num)
    return mid;
   if(a[mid]<=a[left])
   {
       if(num>a[mid]&&num<=a[left])
     return bisearch(a,left,mid-1,num);
    else
     return bisearch(a,mid+1,right,num);
   }
   else
   {
    if(num>=a[right]&&num<a[mid])
     return bisearch(a,mid+1,right,num);
    else
     return bisearch(a,left,mid-1,num);
   }
}
int main()
{
 int a[100]={4,3,2,1,6,5};
    cout<<bisearch(a,0,5,3)<<endl;
 return 0;
}







 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值