1. 程式人生 > >Leetcode 33.搜尋旋轉排序陣列

Leetcode 33.搜尋旋轉排序陣列

搜尋旋轉排序陣列

假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。

( 例如,陣列 [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

 

這道題讓在旋轉陣列中搜索一個給定值,若存在返回座標,若不存在返回-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

二分搜尋法的關鍵在於獲得了中間數後,判斷下面要搜尋左半段還是右半段,我們觀察上面紅色加粗的數字都是升序的,由此我們可以觀察出規律,如果中間的數小於最右邊的數,則右半段是有序的,若中間數大於最右邊數,則左半段是有序的,我們只要在有序的半段裡用首尾兩個陣列來判斷目標值是否在這一區域內,這樣就可以確定保留哪半邊了,程式碼如下

 1 class Solution {
 2     public int search(int[] nums, int target) {
 3         int n=nums.length;
 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(nums[mid]==target) return mid;
 9             else
if(nums[mid]<nums[right]){ 10 if(nums[mid]<target && nums[right]>=target) left=mid+1; 11 else right=mid-1; 12 }else{ 13 if(nums[left]<=target && nums[mid]>target) right=mid-1; 14 else left=mid+1; 15 } 16 } 17 return -1; 18 } 19 }