程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> LeetCode 新題: Find Minimum in Rotated Sorted Array 解題報告-二分法模板解法

LeetCode 新題: Find Minimum in Rotated Sorted Array 解題報告-二分法模板解法

編輯:C++入門知識

LeetCode 新題: Find Minimum in Rotated Sorted Array 解題報告-二分法模板解法


Question Solution Suppose a sorted array 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.   解答1: 這個題目trick的地方在於,它的旋轉pivot次數未知。所以有可能它轉了一圈又轉回了原處   所以我們代碼要處理2種情況: 我們還是用二分法來做。比起全部掃一次,二分法可以做到LogN的復雜度。 1. Sorted       這種情況簡單,先計算出mid的值,如果它處在左右的中間,證明這個數列是正常的sorted,直接返回左邊。   2. 中間斷開(也就是說旋轉過) 我們的目的是要找出存在斷口的地方。所以我們可以每次求一下mid的值,把mid 跟左邊比一下,如果是正常序,就丟掉左邊,反之丟掉右邊,不斷反復直到找到斷口。 分析一下: 比如4 5 6 7 0 1 2  從中間斷開後,它是由一個有序跟一個無序的序列組成的。 如果left = 0, right = 6,mid = 3, 那麼4, 5, 6, 7 是正序, 7, 0, 1, 2是逆序,所以我們要丟掉左邊。這樣反復操作,直到數列中只有2個數字,就是斷開處,這題我們會得到7,0,返回後一個就可以了。   以下圖示簡單描述了通過三步操作逐步逼近斷口處。每一次我們可以扔掉一半,速度是LogN.   【Leetcode】Find <wbr>Minimum <wbr>in <wbr>Rotated <wbr>Sorted <wbr>Array <wbr>解題報告   注意,丟掉半邊時,mid不可以丟掉,因為有可能mid就是答案。 例子: 3, 1, 2 的時候,3, 1是逆序,1, 2是正序,如果你扔掉1,2你就丟掉了答案。  1 // Solution 1:  2     public int findMin1(int[] num) {  3         if (num == null || num.length == 0) {  4             return 0;  5         }  6           7         if (num.length == 1) {  8             return num[0];  9         } 10          11          12         // 至少有2個元素,才有討論的價值  13         int l = 0; 14         int r = num.length - 1; 15          16         while (l < r) { 17             int mid = l + (r - l)/2; 18             // Means that there is no rotate. 19             if (num[mid] >= num[l] && num[mid] <= num[r]) { 20                 return num[0]; 21             } 22              23             // rotate > 0的情況  24             if (l == r - 1) { 25                 // 當只余下2個元素的時候,這裡是斷點,右邊的是小值 26                 return num[r]; 27             } 28              29             if (num[mid] >= num[l]) { 30                 // The left side is sorted. Discard left. 31                 l = mid; 32             } else { 33                 // The right side is sorted. 34                 r = mid; 35             } 36         } 37          38         return 0; 39     } 復制代碼     解答2: 采用九章算法的二分法模板來解: 這個模板最大的好處是 while(left < right - 1) 這樣的話,終止時就一定是left = right - 1,而且mid 一直會是在中間,不會靠到left去。判斷起來會相當 便利。   復制代碼  1 // solution 2:  2     public int findMin(int[] A) {  3         if (A == null || A.length == 0) {  4             return 0;  5         }  6           7         if (A.length == 1) {  8             return A[0];  9         } else if (A.length == 2) { 10             return Math.min(A[0], A[1]); 11         } 12          13         // 至少有3個元素,才有討論的價值  14         int l = 0; 15         int r = A.length - 1; 16          17         while (l < r - 1) { 18             int m = l + (r - l) / 2; 19              20             // means that there is no rotate. 21             if (A[m] < A[r] && A[m] > A[l]) { 22                 return A[0]; 23             } 24              25             // left side is sorted. 26             if (A[m] > A[l]) { 27                 l = m; 28             } else { 29                 r = m; 30             } 31         } 32          33         return A[r]; 34     } 復制代碼   所以以後一定要多使用模板化的編程 ,特別是這裡總結的二分法模板: 復制代碼  1         while (l < r - 1) {  2             int m = l + (r - l) / 2;  3               4             // means that there is no rotate.  5             ... 這裡添加各種退出條件,比如找到了目標值等 8               9             // left side is sorted. 10             if (A[m] > A[l]) { 11                 l = m; 12             } else { 13                 r = m; 14             } 15         }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved