zoukankan      html  css  js  c++  java
  • (算法)旋转有序数组中查找某个数

    题目:

    假设有个有序数组在某个位置旋转,得到新的数组,即为旋转有序数组。如:(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

    现给定一个这样的数组,在数组中查找某个数。如果找到,返回下标,否则返回-1;

    思路:

    思路1:

    考虑一个旋转有序数组的特点:前面部分是递增的,后面部分也是递增的,即先后两部分都为递增有序数组,因此可以用二分查找来做。

    假设数组为A,下标从left到right,查找的数字为target,那么mid=(left+((right-left)>>1))

    如果A[mid]==target,则return mid;

    如果A[mid]>target或者A[mid]<target怎么办呢?以mid为界,左右两边不一定是有序的数组。此时我们先不比较A[mid]和target的大小。

    以mid为界,左右两边必定有一边为递增的有序数组,那么这就是我们要找的区间。

    如果A[mid]>A[left],那么mid的左边部分为递增有序数组,如果target>=A[left] && target<A[mid],那么right=mid-1;否则,left=mid+1;

    如果A[mid]<A[left],那么mid的右边部分为递增有序数组,如果target>A[mid] && target<=A[right],那么left=mid+1;否则,right=mid-1;

    思路2:

    当然,我们也可以从正常的思路去想,分别从A[mid]==target,A[mid]>target,A[mid]<target三部分去考虑边界条件。(详见代码)

    代码:

    #include<iostream>
    
    using namespace std;
    
    int RotateArraySearch_1(int *A,int len,int target){
        int left=0;
        int right=len-1;
        while(left<=right){
            int mid=left+((right-left)>>1);
            if(A[mid]==target)
                return mid;
            if(A[mid]>A[left]){
                if(target>=A[left] && target<A[mid])
                    right=mid-1;
                else
                    left=mid+1;
            }
            else{
                if(target>A[mid] && target<=A[right])
                    left=mid+1;
                else
                    right=mid-1;
            }
        }
        return -1;
    }
    
    
    int RotateArraySearch_2(int *A,int len,int target){
        int left=0;
        int right=len-1;
        while(left<=right){
            int mid=left+((right-left)>>1);
            if(A[mid]==target)
                return mid;
            else if(target>A[mid]){
                if(A[mid]>A[left] || target<=A[right])
                    left=mid+1;
                else
                    right=mid-1;
            }
            else{
                if(A[mid]<A[right] || target>=A[left])
                    right=mid-1;
                else
                    left=mid+1;
            }
        }
        return -1;
    }
    
    int main(){
        int A[]={2,3,4,5,1};
        int B[]={5,1,2,3,4};
        int n=sizeof(A)/sizeof(A[0]);
        cout<< RotateArraySearch_1(A,n,5) <<endl;
        cout<< RotateArraySearch_1(A,n,3) <<endl;
    
        cout<< RotateArraySearch_2(B,n,1) <<endl;
        cout<< RotateArraySearch_2(B,n,4) <<endl;
        return 0;
    }
  • 相关阅读:
    3月1日起执行!江苏居民阶梯电价有变化!
    个体工商户需要报税吗?
    西红柿的选购方法
    正常人一天该走六千还是一万步?步数滚蛋,运动强度和时长才重要,锻炼身体,快走
    NAT四种类型以及提高NAT类型的途径和方法 nat1 nat2 nat3 nat4
    6种沙坦类药物有什么区别, 选哪一种更好? 药师一次说清楚
    心脏神经官能症是什么症状
    呼吸性碱中毒
    Python Serverless 开源框架:Zappa(详细教程)
    不用代码趣讲 ZooKeeper 集群
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4828644.html
Copyright © 2011-2022 走看看