LintCode-62: Search in Rotated Sorted Array (经典Binary Search题)

这题应该是Binary Search题里面最经典的一道了。
注意它跟Rotated Sorted Array里面找minimum要复杂一些。找minimum的题没有target,只需要把A[mid]跟A[start]比较就可以知道是在第二象限还是第四象限,从而把数据分为OOOOXXXX两部分继续二分。

而这道题目需要把A[mid]和target两个值都跟A[start]比较。所以有很多种情况。
case 1: A[mid]==target 直接返回mid即可。
case 2: A[mid]>A[start] && target<A[start] 这种情况说明mid在第一象限,target在第四象限,扔左半边即可。
case 3: A[mid]<A[start] && target>A[start] 这种情况说明mid在第四象限,target在第二象限,扔右半边即可。
case 4: A[mid]<A[start] && target<A[start] 这种情况说明mid在第四象限,target也在第四象限。这个就回到经典的Binary Search了。我们再比较A[mid]和target。如果A[mid]>target,扔右半边,否则扔左半边。
case 5: A[mid]>A[start] && target>A[start] 这种情况说明mid在第一象限,target也在第一象限。比较A[mid]和target。如果A[mid]>target,扔右半边,否则扔左半边。所以case 4和case 5可以合并。

代码如下:

    int search(vector<int> &A, int target) {
        if (A.size()==0) return -1;
        int start=0, end=A.size()-1;
        
        if (A[start]==target) return start;
        if (A[end]==target) return end;
        
        while(start+1<end) {
            int mid=start+(end-start)/2;
            if (A[mid]==target) return mid;
            if (A[mid]>A[start] && target<A[start]) start=mid;
            if (A[mid]<A[start] && target>A[start]) end=mid;
            
            if ((A[mid]<A[start] && target<A[start]) || (A[mid]>A[start] && target>A[start])) {
                if (A[mid]>target) end=mid;
                else start=mid;
            }

        }
        if (A[start]==target) return start;
        if (A[end]==target) return end;
        return -1;
    }

注意:
1)应该把A[mid]和target都跟A[start]比。把A[mid]跟A[start]比,然后A[mid]跟target比是不对的。比如说A[mid]>A[start] (第二象限),A[mid]>target,但我们并不知道target是落在第二象限还是第四象限!
2) 我们一开头需要比较A[start]和A[end]是不是已经等于target。否则A[]={1,2,3},start=0, end=2, mid=1, 然后几个if又都不满足,陷入死循环。

二刷:

class Solution {
public:
    /**
     * @param A: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &A, int target) {
        int n = A.size();
        if (n == 0) return -1;
        
        int start = 0, end = n - 1;
        
        if (A[start] == target) return start;
        if (A[end] == target) return end;
        
        while(start + 1 < end) {
            int mid = start + (end - start) / 2;

            if (A[mid] == target) return mid;

            if (A[mid] > A[start]) {
                if (target < A[mid] && target > A[start]) end = mid;
                else start = mid;
            }
            
            if (A[mid] < A[start]) {
                if (target > A[mid] && target < A[end]) start = mid;
                else end = mid;
            }
            
        }

        if (A[start] == target) return start;
        if (A[end] == target) return end;
        
        return -1;
    }
};

三刷

class Solution {
public:
    /**
     * @param A: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &A, int target) {
        int n = A.size();
        if (n == 0) return -1;
        int start = 0, end = n - 1;
        while (start + 1 < end) {
            int mid =  start + (end - start) / 2;

            if (A[mid] < A[start] && target > A[start]) {
                end = mid;
            } else if (A[mid] > A[start] && target < A[start]) {
                start = mid;
            } else if ((A[mid] > A[start] && target >= A[start]) ||
                       (A[mid] < A[start] && target < A[start])) {
                if (A[mid] > target) {
                    end = mid;
                } else if (A[mid] < target) {
                    start = mid;
                } else {
                    return mid;
                }
            } 
        }
        if (A[end] == target) return end;
        if (A[start] == target) return start;
        return -1;
    }
};

上面可以简化为:

class Solution {
public:
    /**
     * @param A: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &A, int target) {
        int n = A.size();
        if (n == 0) return -1;
        int start = 0, end = n - 1;
        while (start + 1 < end) {
            int mid =  start + (end - start) / 2;
            if (A[mid] < A[start] && target > A[start]) {
                end = mid;
            } else if (A[mid] > A[start] && target < A[start]) {
                start = mid;
            } else {
                if (A[mid] > target) {
                    end = mid;
                } else if (A[mid] < target) {
                    start = mid;
                } else {
                    return mid;
                }
            } 
        }
        if (A[end] == target) return end;
        if (A[start] == target) return start;
        return -1;
    }
};

四刷: <= end就表示在右分支,> end表示在左分支。

class Solution {
public:
    /**
     * @param a: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &a, int target) {
        int aSize = a.size();
        if (aSize == 0) return -1;
        int start = 0, end = aSize -1;

        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if ((target <= a[end] && a[mid] <= a[end]) ||
                (target > a[end] && a[mid] > a[end])) {
                if (target < a[mid]) {
                    end = mid;
                } else {
                    start = mid;
                }
            } else if (target <= a[end] && a[mid] > a[end]) {
               start = mid;
            } else {
                end = mid;
            }
        }
        
        if (a[start] == target) return start;
        if (a[end] == target) return end;
        return -1;
    }
};

五刷:

class Solution {
public:
    /**
     * @param a: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &a, int target) {
        int len = a.size();
        if (len == 0) return -1;
        int start = 0, end = len - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (a[mid] <= a[end])
            {
                if (target >= a[mid] && target <= a[end]) {
                    start = mid;
                } else {
                    end = mid;
                }
            } else {
               if (target <= a[mid] && target > a[end]) {
                   end = mid;
               } else {
                   start = mid;
               }
            }
        }
        if (a[end] == target) return end;
        if (a[start] == target) return start;
        return -1;
    }
};

六刷

class Solution {
public:
    /**
     * @param a: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &a, int target) {
       int n = a.size();
       if (n == 0) return -1;
       int start = 0, end = n - 1;
       while (start + 1 < end) {
           int mid = start + (end - start) / 2;
          // if (a[mid] == target) return mid;
           if (a[mid] > a[start]) { //mid is in the left part
               if (a[start] <= target && target <= a[mid]) { //target is b/w start and mid
                   end = mid;
               } else { //target is b/w mid and end
                   start = mid;
               }
           } else { //mid is in the right part
              if (a[mid] <= target && target <= a[end]) { //target is b/w mid and end
                  start = mid;
              } else {
                  end = mid;
              }
           }
       }
       if (a[start] == target) return start;
       if (a[end] == target) return end;
       return -1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值