1. 程式人生 > 其它 >演算法思想篇-遞迴

演算法思想篇-遞迴

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 int
fabWithArray(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); } }