Search in Rotated Sorted Array I

要搜索的对象是一个rotated sorted array,所以从直觉上时间复杂度应该不会超过O(logn)。解决这个题目的另一个思路就是先把pivot找出来,在这里我把pivot定义为数组中最小的那个数。所以下面要解决的便是能不能在O(logn)的时间找到pivot。沿着这个思路,然后综合rotated sorted array的特征,可以用类似binary serach的方法找到pivot。pivot具有如下特征:pivot左侧和右侧的数均大于pivot本身。而搜索方向的确定可以根据比较当前搜索到的数与A[0]来判断,如果A[current] >= A[0]说明pivot在[current,n]的范围内,反之pivot在[0,current-1]范围内。不过要注意没有pivot的特殊情况,即array是sorted但没有被rotated。

在得到pivot后,我们便可以在pivot划分的两个区域内分别用binary search搜索target。时间复杂度为O(logn)。

 1 class Solution {
 2 public:
 3     int search(int A[], int n, int target) {
 4         int pivot = search_pivot(A,0,n-1);
 5         if(pivot == -1) return binary_search(A,0,n-1,target);
 6         if(target > A[pivot-1] || target < A[pivot] || target < A[0] && target > A[n-1]) return -1;
 7         if(target >= A[0]) return binary_search(A,0,pivot-1,target);
 8         else return binary_search(A,pivot,n-1,target);
 9     }
10     int search_pivot(int A[], int left, int right){
11         if(left >= right) return -1;
12         int mid = (left + right)/2;
13         if(A[mid] < A[0]){
14             if(A[mid-1]>A[mid]) return mid;
15             else  return search_pivot(A, left, mid-1);
16         }else {
17             if(A[mid+1]<A[mid]) return mid+1;
18             else return search_pivot(A,mid + 1,right);
19         }
20     }
21     int binary_search(int A[], int left, int right, int target){
22         if(left > right) return -1;
23         int mid = (left + right)/2;
24         if(A[mid] == target) return mid;
25         if(A[mid] > target) return binary_search(A,left,mid-1,target);
26         if(A[mid] < target) return binary_search(A,mid+1, right,target);
27     }
28 };

 但实际上,这个问题有更简单的解法,即在binary search上做些修改。由于数组被rotated,所以难点在于如何确定搜索的范围。而搜索的范围可以根据target, A[first], A[last], A[mid]之间的比较确定。

 1 Class Solution{
 2    public:
 3       int search(int A[], int n, int target){
 4              int first = 0, last = n - 1;
 5              while(first < =last ){
 6                  int mid = (first + last)/2;
 7                  if(A[mid] == target) return mid;
 8                  if(A[first] <= A[mid] ){
 9                    if(A[first] <=  target && A[mid] > target)
10                        last = mid-1;
11                    else first = mid + 1;
12                  }else {
13                             if(A[mid] < target && A[last] >= target)
14                                  first = mid + 1;
15                             else last = mid - 1;
16                   } 
17              }
18               return -1; 
19       }  
20 };

 

posted on 2014-08-02 14:33  Ryan-Xing  阅读(196)  评论(0)    收藏  举报