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

33. 搜尋旋轉排序陣列Leetcode

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

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

/*
思路:
因為題目要求找到target的時間複雜度為n(logn),所以很容易想到要使用二分法求解
旋轉陣列,就是把後邊的子陣列放到前邊
如: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
經過觀察,我們可以發現總有一半的陣列是有序的
而且發現,在旋轉陣列中,大數在前,小數在後
就比如2,4,5,6,7,0,1
當找到2,4,5,6有序後,剩下的7,0,1中也可以看做是一個旋轉陣列
如果中間的那個數比後邊的那個數小,說明後半段有序
反之,前半段有序
我們在有序的陣列中呼叫二分查詢法
*/
class Solution {
    public int search(int[] nums, int target) {
        
        if(nums == null || nums.length == 0)
            return -1;
    
        int start = 0;
        int end = nums.length - 1;
        
        while(start <= end){
            if(target == nums[start])
                return start;
            
            if(target == nums[end])
                return end;
            
            int middle = (start+end)/2;
            
            if(nums[middle] == target)
                return middle;
                
            if(nums[middle] < nums[end]){ //說明後半段是有序的
                if(nums[middle] < target && target < nums[end]){ //如果target在後半段中
                    start = middle + 1;
                }
                else{
                    end = middle - 1;
                }
            }else{ //說明前半段是有序的
                if(target > nums[start] && target < nums[middle]){
                    end = middle - 1;
                }else{
                    start = middle + 1;
                }
            } 
      }
        return -1;
    }
}```