【LeetCode】Search in Rotated Sorted Array II(转)

原文链接 http://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 

http://blog.csdn.net/linhuanmars/article/details/20588511

这道题是二分查找Search Insert Position的变体,思路在Search in Rotated Sorted Array中介绍过了,不了解的朋友可以先看看那道题哈。和Search in Rotated Sorted Array唯一的区别是这道题目中元素会有重复的情况出现。不过正是因为这个条件的出现,出现了比较复杂的case,甚至影响到了算法的时间复杂度。原来我们是依靠中间和边缘元素的大小关系,来判断哪一半是不受rotate影响,仍然有序的。而现在因为重复的出现,如果我们遇到中间和边缘相等的情况,我们就丢失了哪边有序的信息,因为哪边都有可能是有序的结果。假设原数组是{1,2,3,3,3,3,3},那么旋转之后有可能是{3,3,3,3,3,1,2},或者{3,1,2,3,3,3,3},这样的我们判断左边缘和中心的时候都是3,如果我们要寻找1或者2,我们并不知道应该跳向哪一半。解决的办法只能是对边缘移动一步,直到边缘和中间不在相等或者相遇,这就导致了会有不能切去一半的可能。所以最坏情况(比如全部都是一个元素,或者只有一个元素不同于其他元素,而他就在最后一个)就会出现每次移动一步,总共是n步,算法的时间复杂度变成O(n)。代码如下:

 

[java] view plaincopy
 
  1. public boolean search(int[] A, int target) {  
  2.     if(A==null || A.length==0)  
  3.         return false;  
  4.     int l = 0;  
  5.     int r = A.length-1;  
  6.     while(l<=r)  
  7.     {  
  8.         int m = (l+r)/2;  
  9.         if(A[m]==target)  
  10.             return true;  
  11.         if(A[m]>A[l])  
  12.         {  
  13.             if(A[m]>target && A[l]<=target)  
  14.             {  
  15.                 r = m-1;  
  16.             }  
  17.             else  
  18.             {  
  19.                 l = m+1;  
  20.             }  
  21.         }  
  22.         else if(A[m]<A[l])  
  23.         {  
  24.             if(A[m]<target && A[r]>=target)  
  25.             {  
  26.                 l = m+1;  
  27.             }  
  28.             else  
  29.             {  
  30.                 r = m-1;  
  31.             }                  
  32.         }  
  33.         else  
  34.         {  
  35.             l++;  
  36.         }  
  37.     }  
  38.     return false;  
  39. }  

以上方法和Search in Rotated Sorted Array是一样的,只是添加了中间和边缘相等时,边缘移动一步,但正是这一步导致算法的复杂度由O(logn)变成了O(n)。个人觉得在面试中算法复杂度还是很重要的考察点,因为涉及到对算法的理解,大家还是要尽量多考虑哈。

 

posted @ 2014-05-10 19:53  一弦一仙  阅读(148)  评论(0编辑  收藏  举报