題目: Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
就是說,排序數組可能是右移了一定位數。讓你在這個數組中找一個target值。當然用線性查找就沒意義了。
想這個解法需要頭腦比較清晰。記得原來高中做題,老師最常說的一句話是啥?”要揣摩出題人意圖啊“。。。這道題也是這樣的。如果是在一個有序數組里面找一個值,那么一般都是用binarySearch。現在數組變了,(當然,還保持一些其他特點,我們下面說),能不能用binarySearch呢,或者我們改一下binarySearch呢?
如果用binarySearch,我們在通過Low和High序號得到Mid以后,應該如何剔除一半的數據呢?
下面是rotate后的一個有序數組的圖。四邊形的斜邊表示數組中數值的大小。
在這種情況下數組分了兩部分,分別都是有序(遞增)的。
當我們計算了Mid以后,有兩種可能,分別用Mid1和Mid2表示。
1. 如果A[Low] < A[Mid],說明Mid落在區間1中,即圖中Mid1的位置。那么,如果target小於A[Mid1],那么繼續在Low和Mid1中間搜索;否則,在Mid1和High中間搜索;
2. 如果A[Low] >= A[Mid],說明Mid落在區間2中,即圖中Mid2的位置。同理,如果target小於A[Mid2],那么繼續在Low和Mid2中間搜索;否則,在Mid2和High中間搜索。
這樣,平均地,我們每次剔除一半數據,時間復雜度是O(logn)。
代碼如下:

1 private static int search2(int[] A, int target){ 2 int lo = 0; 3 int hi = A.length - 1; 4 while(lo <= hi){ 5 int mid = lo + (hi - lo)/2; 6 if(target == A[mid]) return mid; 7 if(A[mid] > lo){ 8 if(target >= lo && target < A[mid]){ 9 hi = mid - 1; 10 }else { 11 lo = mid + 1; 12 } 13 }else { 14 if(target <= hi && target > A[mid]){ 15 lo = mid + 1; 16 }else { 17 hi = mid -1; 18 } 19 } 20 } 21 return -1; 22 }