遞迴過程以及遞迴master公式
遞迴過程以及遞迴master公式
遞迴過程
1. 舉個栗子
使用遞迴方式找到陣列中最大的元素,程式碼如下:
public class Recursion { public static void main(String[] args) { int[] arr = new int[]{1, 3, 2, 5, 3, 1, 5, 6}; System.out.println(process(arr, 0, arr.length - 1)); } public static int process(int[] arr, int L, int R) { if (L == R) { return arr[L]; } int mid = L + ((R - L) >> 1); // 中點 int leftMax = process(arr, L, mid); // 找到左邊部分最大值 int rightMax = process(arr, mid + 1, R); // 找到右邊部分最大值 return Math.max(leftMax, rightMax); // 返回兩者中更大的那一個 } }
2. 解釋說明
以 arr = new int[]{1, 3, 7, 5, 6, 2} 來說明(配合下圖一起食用,效果更佳):
最開始呼叫方法為 p ( arr, 0, 5),(因為引數 arr 始終沒有發生改變,之後方法簡寫一下,省略其中的 arr)
然後 p (0, 5) 會先呼叫 p (0, 2) 去找左邊部分最大值 , p (0, 2) 會呼叫 p (0, 1) 去找左邊部分最大值
p (0, 1) 會繼續呼叫 p (0, 0),p(0, 0) 返回值 arr[0] , p(0, 1) 就可以進入到右邊部分找最大值,即呼叫 p (1, 1) ,p (1, 1) 返回 arr[1] 後,p(0, 1) 就可以返回 arr[0] 和 arr[1] 中的最大值
p (0, 1) 返回後,p(0, 2) 就會呼叫 p(2, 2) 去找右邊部分的最大值...
依次類推,直到得到 p(0, 5) 的返回值
題外話:有經驗的小夥伴可以看出來,這實際就是一個二叉樹的後序遍歷; 每次把方法壓入棧,等到方法執行結束後就出棧, 棧空間大小為樹的高度
master 公式
1. 公式說明
用於估計一系列特殊行為的遞迴時間複雜度,為什麼說特殊呢?因為它的使用前提是“分解出的子問題的規模要一樣”,我們先來看一下公式
T(N) = a * T (N/b) + O(N^d)
其中 a 表示的是子規模的次數, 像上面那個例子中 a = 2
b 表示的是子問題的規模, 上面例子中 b = 2, 將問題分為了左邊最大和右邊最大兩個子問題
式子最後的 O( ) 表示的是除去呼叫子過程的其他時間複雜度, 上面例子中為O(1), 因為除去呼叫子過程,剩下的步驟就是判斷相等和取出兩者之中的最大值,時間複雜度為常數階,因此 d = 0
2. 公式求解
那得到 a, b, d 的值有什麼用呢?我們可以通過這三個值快速得到遞迴演算法的時間複雜度
序號 | 條件 | 時間複雜度 |
---|---|---|
1 | logb a < d | O(N^d) |
2 | logb a > d | O(N^ (logb a)) |
3 | logb a = d | O(N^d * log N) |
那通過上述例子的 a = 2, b = 2, d = 0, 可得 logb a = 1 > 0, 為情況 2,時間複雜度為 O(N)
歡迎大家來我部落格逛逛 mmimo技術小棧