你們都知道斐波那契數列,如今要求輸入一個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項爲0)。
n<=39java
遞歸(函數棧調用消耗過高)
時間複雜度O(n),空間複雜度O(n)。算法
使用循環替換遞歸
時間複雜度O(n),空間複雜度O(1)。函數
動態規劃
時間複雜度O(n),空間複雜度O(1)。code
矩陣快速冪
時間複雜度O(lgn),空間複雜度O(1)。blog
public class Solution { public int Fibonacci(int n) { if(n < 0) return 0; if(n < 2) return n; return Fibonacci(n-1)+Fibonacci(n-2); } }
public class Solution { public int Fibonacci(int n) { int a = 0, b = 1, c = 1; while(n-- > 0) { a = b; b = c; c = a + b; } return a; } }
public class Solution { public int Fibonacci(int n) { int[] dp = new int[] {0, 1}; while(n-- > 0) { dp[1] = dp[0] + dp[1]; dp[0] = dp[1] - dp[0]; } return dp[0]; } }
class Solution { private int[][] matmul(int[][] a, int[][] b, int m, int n, int t) { int[][] tmp = new int[m][n]; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { tmp[i][j] = 0; for(int k = 0; k < t; k++) { tmp[i][j] += a[i][k] * b[k][j]; } } } return tmp; } public int Fibonacci(int n){ if(n < 1) return 0; if(n == 1) return 1; int[][] matT = new int[][] {{1, 1}, {1, 0}}; int[][] fibT = new int[][] {{1}, {0}}; while(n > 1){ // 二進制轉換,最高位1用最終快速冪矩陣,其他位1用當前冪矩陣 if(n%2 == 1){ fibT = matmul(matT, fibT, 2, 1, 2); } matT = matmul(matT, matT, 2, 2, 2); n /= 2; } fibT = matmul(matT, fibT, 2, 1, 2); return fibT[1][0]; } }
快速冪餘項的個數聯想二進制權重。
遞歸