LintCode:62. 搜索旋转排序数组 VS 63. 搜索旋转排序数组II

题目:


分析:看到排序数组的查找问题,就要想到二分查找。旋转排序数组其实是由两个递增子数组组成,且前一个子数组中的任意元素都大于后一个数组中元素。left,right分别是指向数组首尾的两个指针。

循环条件:left<=right

  1. 若A[mid]==target,表示
  2. 若A[mid]>A[left],表示left与mid均处于前一个递增数组中。

            若target>=A[left]且target<A[mid],则right=mid-1;否则,left=mid+1;

    3. 若A[mid]<A[left],表示right与mid均处于前一个递增数组中。

            若target>A[mid]且target<=A[right],则left=mid+1;否则,right=mid-1;

public class Solution {
    /**
     * @param A: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    public int search(int[] A, int target) {
        // write your code here
        if(A.length==0 || A==null)  return -1;
        int len=A.length;
        int left=0,right=len-1;
        while(left<=right){
            //注意到前面的递增子序列中任意元素都大于后面的递增子序列
            int mid=(left+right)/2;
            if(A[mid]==target){
                return mid;
            }else if(A[mid]>A[left]){  //中间元素大于left位置,表示中间元素和位于前面递增子序列中
                if(target>=A[left] && target<A[mid]){  //正常的二分查找
                    right=mid-1;
                }else{
                    left=mid+1;
                }
            }else{  //中间元素小于left位置,表示中间元素位于后面递增子序列中
                if(target>A[mid] && target<=A[right]){
                    left=mid+1;
                }else{
                    right=mid-1;
                }
            }
        }
        return -1;
    }
}

思路同62一样,题面的区别是62中数组不存在相同元素,63是数组存在相同元素,同样采用二分查找的方法,需要额外考虑一种情况:

当A[mid]==A[left]时,表示mid与left的数值相同,因为存在相同元素的原因,所以left与mid之间的数组并不一定是递增的,所以此时需要顺序查找A[left:mid-1],所以left++;比如[1,0,1,1,1]的情况,A[left]=A[mid]=1。

public class Solution {
    /**
     * @param A: an integer ratated sorted array and duplicates are allowed
     * @param target: An integer
     * @return: a boolean 
     */
    public boolean search(int[] A, int target) {
        // write your code here
        if(A.length==0 || A==null)  return false;
        int len=A.length;
        int left=0,right=len-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(A[mid]==target){
                return true;
            }else if(A[mid]>A[left]){
                if(target<A[mid] && target>=A[left]){
                    right=mid-1;
                }else{
                    left=mid+1;
                }
            }else if (A[mid]<A[left]){
                if(target<=A[right] && target>A[mid]){
                    left=mid+1;
                }else{
                    right=mid-1;
                }
            }else{ //A[mid]==A[left]
                left++;
            }
        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27139155/article/details/80510894