LeetCode 熱題 HOT 100 Java題解——33. 搜尋旋轉排序陣列

可達鴨丶發表於2020-09-28

LeetCode 熱題 HOT 100 Java題解

33. 搜尋旋轉排序陣列

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

( 例如,陣列 [ 0 , 1 , 2 , 4 , 5 , 6 , 7 ] [0,1,2,4,5,6,7] [0,1,2,4,5,6,7] 可能變為 [ 4 , 5 , 6 , 7 , 0 , 1 , 2 ] [4,5,6,7,0,1,2] [4,5,6,7,0,1,2] )。

搜尋一個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1 。

你可以假設陣列中不存在重複的元素。

你的演算法時間複雜度必須是 O ( l o g n ) O(log n) O(logn) 級別。

示例:

輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4

二分法

一看要求需要 O ( l o g n ) O(log n) O(logn) 級別,大概率是二分法,這種旋轉的條件下其實也只是多了一些條件判斷而已,個人認為和有序陣列的二分查詢基本沒有什麼區別:

求出中點後,由於有序旋轉的特殊性質,至少有一半陣列是有序的,因此只有兩種情況:

  1. 左邊有序, n u m s [ s t a r t ] < = n u m s [ m i d ] nums[start] <= nums[mid] nums[start]<=nums[mid],如果 t a r g e t target target在這個範圍裡,那麼就遞迴的找左邊,否則右邊。
  2. 右邊有序, n u m s [ m i d ] < = n u m s [ e n d ] nums[mid] <= nums[end] nums[mid]<=nums[end],同1,情況相反。
class Solution {
    public int binarySearch(int[] nums, int start, int end, int target) {
        if(start > end) return -1;
        int mid = (end - start) / 2 + start;
        if(target == nums[mid]) return mid;
        else if(nums[start] <= nums[mid]) {
            if(target < nums[mid] && target >= nums[start]) return binarySearch(nums, start, mid - 1, target);
            else return binarySearch(nums, mid + 1, end, target);
        }
        else {
            if(target > nums[mid] && target <= nums[end]) return binarySearch(nums, mid + 1, end, target);
            else return binarySearch(nums, start, mid - 1, target);
        }
    }
    public int search(int[] nums, int target) {
        return binarySearch(nums, 0, nums.length - 1, target);
    }
}

複雜度分析

  • 時間複雜度: O ( l o g n ) O(logn) O(logn)

    折半查詢複雜度為 O ( l o g n ) O(logn) O(logn)

  • 空間複雜度: O ( 1 ) O(1) O(1)

    由於是尾遞迴,因此優化後也只消耗常數級別的空間複雜度。

相關文章