斐波那契數,通常表示為 F(n),形成一個序列,稱為斐波那契數列,其中每個數都是前兩個數的和,從 0 和 1 開始。即,
F(0) = 0, F(1) = 1
F(n)=F(n-1)+F(n-2),對於n>1 1.
給定 n,計算 F(n)。
範例1:
輸入:n = 2
輸出:1
解釋:F(2) = F(1) + F(0) = 1 + 0 = 1.
範例2:
輸入:n = 3
輸出:2
解釋:F(3) = F(2) + F(1) = 1 + 1 = 2.
範例 3:
輸入:n = 4
輸出:3
解釋:F(4) = F(3) + F(2) = 2 + 1 = 3.
限制:
0 原始頁
public int fib(int n) { if(n==0){ return 0; } else if(n==1){ return 1; } else{ return fib(n-1) + fib(n-2); } }
遞歸法就像DFS一樣,深入進行,然後回溯得到最終答案。
時間:O(2^n)
空間:O(1)
private int[] dp = new int[31]; public int fib(int n) { if(n<2){ dp[n] = n; return n; } if(n>=2 && dp[n]!=0){ return dp[n]; } dp[n] = fib(n-1) + fib(n-2); return dp[n]; }
我們可以使用全域數組來保存結果,以避免相同元素的重複遞歸。例如下圖顯示 f(17) 和 f(18) 是兩種不同的遞迴路線,如果我們使用正常的遞迴方法,我們必須多次計算它們。
時間:O(n),空間:O(n)
public int fib(int n) { if(n<2){ return n; } int[] dp = new int[n+1]; dp[0] = 0; dp[1] = 1; for(int i=2; i<=n; i++){ dp[i] = dp[i-1] + dp[i-2]; } return dp[n]; }
遞迴是從上到下再回溯,記憶體遞歸會保存遞迴結果,避免重複計算。現在動態規劃從下到上進行,並將每個步驟的結果儲存到 dp 陣列中。
時間:O(n)
空間:O(n)
public int fib(int n) { if(n<2){ return n; } int start = 0; int pre = 1; int res = pre; for(int i=2; i<=n; i++){ res = start + pre; start = pre; pre = res; } return res; }
您正在爬樓梯。需要n步才能到達山頂。
每次可以爬 1 或 2 級階梯。您可以透過多少種不同的方式登上頂峰?
範例1:
輸入:n = 2
輸出:2
說明:有兩種方法可以登頂。
輸入:n = 3
輸出:3
說明:共有三種方法可以登頂。
您正在爬樓梯。需要n步才能到達山頂。
每次可以爬 1 或 2 級階梯。您可以透過多少種不同的方式登上頂峰?
範例1:
輸入:n = 2
輸出:2
說明:有兩種方法可以登頂。
輸入:n = 3
輸出:3
說明:共有三種方法可以登頂。
限制:
1 原始頁
public int climbStairs(int n) { if(n<3){ return n; } int[] dp = new int[n+1]; dp[0] = 0; dp[1] = 1; dp[2] = 2; for(int i=3; i<=n; i++){ dp[i] = dp[i-1] + dp[i-2]; } return dp[n]; }
public int climbStairs(int n) { if(n<3){ return n; } int prepre = 1; int pre = 2; int res = 0; for(int i=3; i<=n; i++){ res = prepre + pre; prepre = pre; pre = res; } return res; }
給定一個整數數組 cost,其中 cost[i] 是樓梯上第 i 步的成本。支付費用後,您可以爬一層或兩層台階。
您可以從索引 0 的步驟開始,也可以從索引 1 的步驟開始。
返回到達樓層頂部的最低成本。
範例1:
輸入:成本 = [10,15,20]
輸出:15
說明:您將從索引 1 開始。
輸入:成本 = [1,100,1,1,1,100,1,1,100,1]
輸出:6
說明:您將從索引 0 開始。
限制:
2
0
原始頁
public int minCostClimbingStairs(int[] cost) { if(cost.length < 2){ return 0; } int[] dp = new int[cost.length+1]; dp[0] = 0; dp[1] = 0; for(int i=2; i<dp.length; i++){ dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]); } return dp[dp.length-1]; } the key thing of this problem is the `init array` and `the meaning of the array` and the `Recurrence relation`
以上是LeetCode Day動態程式設計第1部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!