Medium!
題目描述:
假設按照升序排序的數組在預先未知的某個點上進行了旋轉。
( 例如,數組 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
搜索一個給定的目標值,如果數組中存在這個目標值,則返回它的索引,否則返回 -1 。
你可以假設數組中不存在重復的元素。
你的算法時間復雜度必須是 O(log n) 級別。
示例 1:
輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4
示例 2:
輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1
解題思路:
這道題讓在旋轉數組中搜索一個給定值,若存在返回坐標,若不存在返回-1。我們還是考慮二分搜索法,但是這道題的難點在於我們不知道原數組在哪旋轉了,我們還是用題目中給的例子來分析,對於數組[0 1 2 4 5 6 7] 共有下列七種旋轉方法:
0 1 2 4 5 6 7
7 0 1 2 4 5 6
6 7 0 1 2 4 5
5 6 7 0 1 2 4
4 5 6 7 0 1 2
2 4 5 6 7 0 1
1 2 4 5 6 7 0
二分搜索法的關鍵在於獲得了中間數后,判斷下面要搜索左半段還是右半段,我們觀察上面紅色加粗的數字都是升序的,由此我們可以觀察出規律,如果中間的數小於最右邊的數,則右半段是有序的,若中間數大於最右邊數,則左半段是有序的,我們只要在有序的半段里用首尾兩個數組來判斷目標值是否在這一區域內,這樣就可以確定保留哪半邊了,代碼如下
C++解法:
1 class Solution { 2 public: 3 int search(int A[], int n, int target) { 4 if (n == 0) return -1; 5 int left = 0, right = n - 1; 6 while (left <= right) { 7 int mid = (left + right) / 2; 8 if (A[mid] == target) return mid; 9 else if (A[mid] < A[right]) { 10 if (A[mid] < target && A[right] >= target) left = mid + 1; 11 else right = mid - 1; 12 } else { 13 if (A[left] <= target && A[mid] > target) right = mid - 1; 14 else left = mid + 1; 15 } 16 } 17 return -1; 18 } 19 };
