現有一個有序數組,假設從某個數開始將它後面的數按順序放到了數組前面。(即 [0,1,2,4,5,6,7] 可能變成 [4,5,6,7,0,1,2])。算法
請找出數組中的最小元素。數組
數組中不包含重複元素。ide
樣例1spa
輸入:[3,4,5,1,2]code
輸出:1blog
樣例2排序
輸入:[4,5,6,7,0,1,2]leetcode
輸出:0get
算法(二分) O(logn)
處理這種問題有個經常使用技巧:若是不想處理邊界狀況,好比當數組只有兩三個數的時候,代碼會出問題。咱們能夠在數組長度過短(這道題中咱們判斷數組長度小於5)時,直接暴力循環作;數組有必定長度時再用二分作。
這樣作並不會影響算法的時間複雜度,但會縮短寫代碼的時間。it
爲了便於理解,咱們將數組中的數畫在二維座標系中,橫座標表示數組下標,縱座標表示數值,以下所示:
咱們會發現數組中最小值前面的數 nums[i]nums[i] 都知足:nums[i]≥nums[0],其中nums[n−1] 是數組最後一個元素;而數組中最小值後面的數(包括最小值)都不知足這個條件。
因此咱們能夠二分出最小值的位置。
另外,不要忘記處理數組徹底單調的特殊狀況。
時間複雜度分析:二分查找,因此時間複雜度是 O(logn)。
1 class Solution { 2 public: 3 int findMin(vector<int>& nums) { 4 if ( nums[0] < nums.back() ) return nums[0] ; 5 int L = 0 , R = nums.size() -1 , Mid , ans = 0 ; 6 while ( L < R ){ 7 Mid = L+R >> 1 ; 8 if( nums[0] <= nums[Mid] ){ 9 ans = Mid ; 10 L = Mid + 1 ; 11 }else { 12 R = Mid ; 13 } 14 } 15 return nums[L] ; 16 } 17 };