LeetCode(80)Search in Rotated Sorted Array II

题目如下:

Follow up for "Search in Rotated Sorted Array":
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.

分析如下:

在有重复元素的情况下,如果使用上一题的代码,就会出错。比如在这样的例子中,在{1,3,1,1,1}中找3,上一题代码中的else if(A[mid]>=A[l])就会判断失效。
解决这个问题可以这样。分情况处理。第一种情况,如果出现了重复,也就是说如果A[mid]==A[i],那么就既不丢弃mid左半部分,也不丢弃mid右半部分,老老实实地只丢弃一个元素。第二种情况,如果没有出现重复,就进行和上一题一样的处理。

我的代码:

//72ms过大集合
class Solution {
public:
    bool search(int A[], int n, int target) {
        int l=0;
        int r=n-1;
        while(l<=r){
            int mid=l+(r-l)/2;
            if(A[mid]==target){
                return true;
            }else if(A[mid]==A[l]){
                    l++; //出现重复,所以没法丢弃一半的元素,只能丢弃1个元素。
            }else if(A[mid]>A[l]){
                if(target<A[mid]&&target>=A[l])
                    r=mid-1;
                else
                    l=mid+1;
            }else {
                if(target<=A[r]&&target>A[mid])
                    l=mid+1;
                else
                    r=mid-1;
            }
        }
        return false;
    }
};


希望优化一下这段代码。一旦遇到重复,每次只能丢弃1个元素,太少了,那么可以这样做,就能提速一些。
// 48ms过大集合
class Solution {
public:
    bool search(int A[], int n, int target) {
        int l=0;
        int r=n-1;
        while(l<=r){
            int mid=l+(r-l)/2;
            if(A[mid]==target){
                return true;
            }else if(A[mid]==A[l]){
                int mid_mid=l+(mid-l)/2;//找到mid和l的中点mid_mid,
                if(A[mid_mid]==target)
                    return true;
                if(A[mid_mid]>A[l])//判断从l到mid_mid是否单调递增。如果是,pivot必然不在这个区间,这个区间单调递增,转化为最常规的情况了。
                    if(target<A[mid_mid]&&target>=A[l])
                        r=mid-1;
                    else
                        l=mid+1;
                else//否则,从l到mid_mid就不是单调递增,说明pivot可能出现在这个区间,没法确定它在哪里,所以每次只能丢弃1个元素。
                    l++;
            }else if(A[mid]>A[l]){
                if(target<A[mid]&&target>=A[l])
                    r=mid-1;
                else
                    l=mid+1;
            }else {
                if(target<=A[r]&&target>A[mid])
                    l=mid+1;
                else
                    r=mid-1;
            }
        }
        return false;
    }
};

update : 2015-01-20

其实这道题目这么理解就比较容易了。

如果没有重复元素,就用Search in Rotated Sorted Array 这道题目的思路,进行一个类似分查找的查找,每次丢弃当前数组的一半。如果有重复元素,每次只能丢弃一个。


迭代版本

// 迭代版本 12ms 
class Solution {
public:
    bool search(int A[], int n, int target) {
        int start = 0, end = n - 1, mid = 0;
        while (start <= end) {
            mid = start + (end -start) / 2;
            if (A[mid] == target)  {
                return true;
            } else if (A[mid]== A[start]) {
               start = start + 1;  
            } else if (A[mid] == A[end]) {
                end = end -1;
            } else if (A[mid] > A[end]) {
                if (target < A[mid] && target >= A[start])
                    end = mid - 1;
                else 
                    start = mid + 1;
            } else {
                if (target > A[mid] && target <= A[end])
                    start = mid + 1;
                else 
                    end = mid - 1;
            }
        }
        return false;
    }
};



递归版本

//递归版本 10ms
class Solution {
public:
    bool search(int A[], int start, int end, int target) {
        if ( start > end ) return false;
        int mid = start + (end - start) / 2 ;
        if (target == A[mid]) {
            return true;
        }else if (A[mid] == A[end]) {
            return search(A, start, end - 1, target);
        }else if (A[mid] == A[start]) {
            return search(A, start + 1, end, target);
        } else if (A[mid] > A[end]) {
            if (target < A[mid] && target >= A[start])
                return search (A, start, mid - 1, target);
            else 
                return search (A, mid + 1, end, target);
        }else {
            if (target > A[mid] && target <= A[end])
                return search (A, mid + 1, end, target);
            else 
                return search(A, start, mid - 1, target);
        }
    }
    
    bool search(int A[], int n, int target) {
        return search (A, 0, n - 1, target);    
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值