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;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值