LeetCode題解(Java實現)——33.Search in Rotated Sorted Array(循環有序數組)

前言

歡迎關注我的 Github 倉庫 https://github.com/bigrotor187/awesome-java-notes ,如果覺得有幫助,請點個 star 喲,目前主要在更 leetcode題解(Java版)劍指offer題解(Java版),可以點個star

文本已收錄至我的GitHub倉庫,歡迎Star:awesome-java-notes

33. Search in Rotated Sorted Array

Description

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

( 例如,數組 [0,1,2,4,5,6,7] 可能變爲 [4,5,6,7,0,1,2] )。

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

你可以假設數組中不存在重複的元素。

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

Example 1:

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

Example 2:

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

Example 3:

輸入:head = [1], pos = -1
輸出:no cycle
解釋:鏈表中沒有環。

Tags: Array, Binary Search

思路 0

參考這裏

循環鏈表中存在這樣一個性質(事實):將數組從中間點劈開,會將數組分成兩部分,分別是循環有序數組部分和有序數組部分。

爲了找到目標元素 target,我們可以先找到數組的有序部分,然後再判斷目標元素是否在有序數組部分中。

  • 如果首元素小於中間元素mid,那麼前半部分是有序的,後半部分是循環有序數組(如 4 5 6 7 8 1 2 3);
  • 如果首元素大於中間元素 mid,那麼後半部分是有序的,前半部分是循環有序數組(如 5 6 1 2 3 4);
  • 如果 target 在有序數組部分中,則對有序部分使用二分查找;
  • 如果目標元素在循環有序數組中,則重新設定數組邊界後,重複上述步驟。

上述中,將數組 4 5 6 7 8 1 2 3 從中間元素 7(mid = 3) 劈開後分成了 4 5 6 的有序數組部分以及 8 1 2 3 的循環有序數組部分。

時間複雜度: O(logn)

空間複雜度: O(1)

public int search(int[] nums, int target) {
        int start = 0;
        int end  = nums.length - 1;
        while (start <= end) {
            int mid = start + ((end - start) >> 2);
            if (target == nums[mid]) {
                return mid;
            }
            // 前面部分有序
            // 千萬要注意這裏的條件是 `nums[start] <= nums[mid]`,而不是 `nums[start] < nums[mid]`
            if (nums[start] <= nums[mid]) {
                if (target >= nums[start] && target < nums[mid]) {
                   end = mid - 1;
                } else {
                    start = mid + 1;
                }
            // 後半部分有序
            } else {
                if (target > nums[mid] && target <= nums[end]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
        }
        return -1;
    }

結語

如果你同我一樣想要征服數據結構與算法、想要刷 LeetCode,歡迎關注我 GitHub 上的 LeetCode 題解:awesome-java-notes

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章