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;
    }
  • 相关阅读:
    SQL Server, Timeout expired.all pooled connections were in use and max pool size was reached
    javascript 事件调用顺序
    Best Practices for Speeding Up Your Web Site
    C语言程序设计 使用VC6绿色版
    破解SQL Prompt 3.9的几步操作
    Master page Path (MasterPage 路径)
    几个小型数据库的比较
    CSS+DIV 完美实现垂直居中的方法
    由Response.Redirect引发的"Thread was being aborted. "异常的处理方法
    Adsutil.vbs 在脚本攻击中的妙用
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4828644.html
Copyright © 2011-2022 走看看