1. 程式人生 > >【LeetCode & 劍指offer刷題】查詢與排序題7:11旋轉陣列的最小數字(153. Find Minimum in Rotated Sorted Array)(系列)

【LeetCode & 劍指offer刷題】查詢與排序題7:11旋轉陣列的最小數字(153. Find Minimum in Rotated Sorted Array)(系列)

【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...)

153. Find Minimum in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e.,   [0,1,2,4,5,6,7]  might become   [4,5,6,7,0,1,2]
). Find the minimum element. You may assume no duplicate exists in the array. Example 1: Input: [3,4,5,1,2] Output: 1 Example 2: Input: [4,5,6,7,0,1,2]
Output: 0
  /* 從頭到尾遍歷一遍為O(n) */   /* 問題:找旋轉有序(增序)陣列(不含重複數)中的最小數 分析:     旋轉後,會形成兩個有序左右子陣列,且左子陣列的數一定比右子陣列的數大
    如[3,4,5,1,2] 方法:二分查詢 O(logn), O(1) */ class Solution { public :     int findMin ( vector < int > & nums )      {         int left = 0 , right = nums . size () - 1 ;         if ( nums [ left ] > nums [ right ]) //若有旋轉          {             while ( left <   right - 1 )              {                 int mid = ( left + right ) / 2 ;                 if ( nums [ left ] < nums [ mid ]) //若中間的數大,移動left指標到中間                     left = mid ;                 else                         //若中間的數小,移動right指標到中間                     right = mid ;             } //退出時,left = right -1,left指向左子陣列的末尾,right指向右子陣列的開頭             return nums [ right ];         }         else //若無旋轉,直接返回第一個數             return nums [ 0 ];     } }; /* 其他寫法     if (nums[mid] < nums[right]) //這種寫法表示,右半段是有序的         right = mid;     else                                 left = mid; */
  154 .   Find Minimum in Rotated Sorted Array II Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e.,   [0,1,2,4,5,6,7]  might become   [4,5,6,7,0,1,2] ). Find the minimum element. The array may contain duplicates. Example 1: Input: [1,3,5] Output: 1 Example 2: Input: [2,2,2,0,1] Output: 0 Note:
  /* 問題:找旋轉有序(增序)陣列(含重複數)中的最小數 分析:     旋轉後,會形成兩個有序左右子陣列,且左子陣列的數一定比右子陣列的數大(或等於)     如[2,2,2,0,1,1,2] 方法:二分查詢,遇到相同數字時,left右移一位 平均O(logn),最壞O(n) */ class Solution { public :     int findMin ( vector < int > & nums )      {         if ( nums . empty ()) return 0 ;         if ( nums . size () == 1 ) return nums [ 0 ];                 int res = nums [ 0 ];         int left = 0 , right = nums . size () - 1 ;         if ( nums [ left ] >= nums [ right ]) //若有旋轉,由於有重複數字,故這裡變為大於等於         {             while ( left < right - 1 )             {                 int mid = ( left + right ) / 2 ;                 if ( nums [ left ] < nums [ mid ]) //若中間的數大,移動left指標到中間                 {                     res = min ( res , nums [ left ]);                     left = mid ;                 }                 else if ( nums [ left ] > nums [ mid ]) //若中間的數小,移動right指標到中間                 {                     res = min ( res , nums [ right ]);                     right = mid ;                 }                 else //若left與mid指向數字相等,將left右移一位,略過相同數字                     left ++;             } //退出時,left = right -1,left指向左子陣列的末尾或右子陣列的開頭             res = min ( res , nums [ left ]);             res = min ( res , nums [ right ]);             return res ;                     }         else //若無旋轉             return nums [ 0 ];     } };