演算法思想篇-遞迴
阿新 • • 發佈:2022-03-25
1.什麼情況下使用遞迴
可以將一個問題分解為很多子問題
這個問題的求解思路與子問題的思路完全一樣
有遞迴的終止條件
2.斐波那契
package com.jun.algorithm.foundation.thought; import org.junit.Test; /** * 斐波那契 * 遞迴的條件: * 一個問題可以分為幾個子問題 * 子問題的求解思路都是完全一樣 * 存在遞迴的終止條件 * <p> * 這裡將會一步步的優化 * 先遞迴,然後迴圈,然後使用快取,最後使用尾遞迴方式 */ public class Fibonacci {/** * 遞迴方式 * 時間複雜度:2^n */ public int fab(int n) { if (n <= 2) { return 1; } return fab(n - 1) + fab(n - 2); } /** * 迴圈 * 時間複雜度 n * * @param n */ public int noFab(int n) { if (n <= 2) {return 1; } int a = 1; int b = 1; int c = 0; for (int i = 3; i <= n; i++) { c = a + b; a = b; b = c; } return c; } private int[] data = new int[6]; /** * 使用快取,計算過的不在計算了 */ public intfabWithArray(int n) { if (n <= 2) { return 1; } if (data[n] > 0) { return data[n]; } int result = fabWithArray(n - 1) + fabWithArray(n - 2); data[n] = result; return result; } /** * 尾遞迴 * 倒著算 * 傳遞結果 * preResult:上次的結果 * result:當前的結果 * <p> * 尾遞迴的條件: * 最後的返回,不要再做任何的操作 */ public int tailFab(int n, int preResult, int result) { if (n <= 2) { return result; } // 傳遞下去,再做一步計算 return tailFab(n - 1, result, preResult + result); } @Test public void test() { int fab = fab(6); int noFab = noFab(6); System.out.println("noFab=" + noFab); System.out.println("fab=" + fab); int i = tailFab(6, 1, 1); System.out.println("fabWithArray=" + i); } }