創造し続け、成長を加速!本日は「ナゲッツデイリー新プラン・10月アップデートチャレンジ」参加初日、イベント詳細はこちら
動的計画法は、意思決定の問題を段階的に解決する数学的アイデアであり、元の問題を単純なサブ問題に分解することで複雑な問題を解決します。
階段を上る
あなたが階段を上っているとします。n
上に行くにはステップが必要 です。
1
一度に 1つ 2
以上のステップを登ることができ ます。建物の最上部に到達する方法は何通りありますか?
例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
复制代码
例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
复制代码
暴力の法則
可能なすべてのステップを組み合わせて、直接再帰的に登り、解決することができます。
上の図に示すように、ブルート フォース ソリューションには多くの分岐が繰り返されるため、時間の複雑さが非常に高くなる必要があります。
動的計画法:
1~2段ずつ登れるので、n-2やn-1からn段目まで上がることができます。
f[n] を使用して n ステップを表す方法はいくつかあります。その場合、f[n]=f[n-1]+f[n-2];
2 つの特殊なケースを考えてみましょう
- n=1 のとき、f(1)=1、つまり手は 1 つだけです。
- n=2、f(2)=2のとき、つまり1次+1次または2次の2通りの動きがある
達成
class Solution {
public int climbStairs(int n) {
if (n==1){
return 1;
}else if (n==2){
return 2;
}else{
int[] dp=new int[n+1];
dp[1]=1;
dp[2]=2;
for (int i=3;i<=n;++i) {
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
}
}
复制代码
複雑さの分析:
- 時間計算量
O(n)
: f(n) の計算に 1 ループかかります。 - 空間の複雑さ
O(n)
: dp 配列は、n 次の動きを記録するために使用されます。ただし、このトピックの f(n) は最初の 2 つの項目 f(n-1) と f(n-2) にのみ関連するため、2 つの変数レコードを直接使用でき、スペースの複雑さを O( 1) )
class Solution {
public:
int climbStairs(int n) {
int p1 = 0, p2 = 0, current = 1;
for (int i = 1; i <= n; ++i) {
p1 = p2;
p2 = current;
current = p1 + p2;
}
return current;
}
};
复制代码
- 時間の複雑さ: O(n)
- スペースの複雑さ: O(1)