あなたが階段を登っているとします。建物の屋上に着くまでにn歩かかります。
一度に1段か2段ずつ登ることができます。建物の屋上に登るには、何通りの方法がありますか?
注: n は正の整数です。
例 1:
入力: 2 出力: 2 説明: 建物の頂上に登るには 2 つの方法があります。
- 1レベル+1レベル
- レベル2
例 2:
入力: 3 出力: 3 説明: 建物の頂上に登るには 3 つの方法があります。
- 1レベル + 1レベル + 1レベル
- レベル1 + レベル2
- レベル2 + レベル1
この問題は典型的な動的計画法の問題です。n 番目のステップは、n-1 または n-2 番目のステップからのみ上がることができます。n-1番目のステップに行く方法 + n-2番目のステップに行く方法 = n番目のステップに行く方法 1番目と2番目のステップに行く方法はすでにわかっているので、それらを追加できます途中で。
f(x)=f(x−1)+f(x−2)
C++
class Solution {
public:
int climbStairs(int n) {
if(n == 1){
return 1;}
if(n == 2){
return 2;}
int a = 1, b = 2, temp;
for(int i =3; i <= n; i++){
temp = a;
a = b;
b = temp + b;
}
return b;
}
};
ジャワ
このプログラムの一般的な考え方は、ループが最初のステップから始まることを除いて、上記の C++ プログラムと同じです。
class Solution {
public int climbStairs(int n) {
if(n < 3){
return n;
}
int p = 0, q = 0 , r = 1;
for(int i = 1; i <= n; i++){
p = q;
q = r;
r = p + q;
}
return r;
}
}
C言語
前の方法では、f(n)f(n) が同次線形漸化式であることを説明しましたが、漸化式によれば f(n) = f(n - 1) + f(n - 2)f(n) =f (n−1)+f(n−2) の場合、次のように特性方程式を書くことができます。
int climbStairs(int n){
double sqrt5 = sqrt(5);
double fibn = pow((1 + sqrt5) / 2, n + 1) - pow((1 - sqrt5) / 2, n + 1);
return (int) round(fibn / sqrt5);
}