これは、これまでのコメントの1つで簡単に述べたように、実際にはフィボナッチ数列と密接に関連しています。各ステップn
は、2ステップ下(n-2
)または1ステップ下(n-1
)のいずれかから到達できるため、到達する可能性の数そのステップは、これらの他の2つのステップに到達する可能性の合計です。最後に、最初のステップ(およびゼロ番目、つまり地面にとどまる)に到達する可能性は1つだけです。
また、stepの可能性の数は、 stepとn
の結果にのみ依存するため、これらの中間値をすべてマップまたは配列に格納する必要はありません。最後の2つで十分です。n-1
n-2
public static long possForStep(int n) {
// current and last value, initially for n = 0 and n = 1
long cur = 1, last = 1;
for (int i = 1; i < n; i++) {
// for each step, add the last two values and update cur and last
long tmp = cur;
cur = cur + last;
last = tmp;
}
return cur;
}
これにより、コードの量が大幅に削減されるだけでなく、すべての中間値を格納するときの時間と空間のO(n)とは対照的に、時間と空間のO(1)の複雑さが増します。 。
ただし、いずれにせよ100に近づくlong
と型もすぐにオーバーフローするため、 O(n)のスペースの複雑さは実際には問題ではないため、読みやすいこのソリューションを使用することもできます。n
public static long possForStep(int n) {
long[] values = new long[n+1];
for (int i = 0; i <= n; i++) {
// 1 for n==0 and n==1, else values[i-1] + values[i-2];
values[i] = (i <= 1) ? 1 : values[i-1] + values[i-2];
}
return values[n];
}
更新:これはフィボナッチ数列に近いが、これとはまったく同じではないことに注意してください。フィボナッチ数列は、これが進行している間に開始され0, 1, 1, 2, 3,...
ます。1, 1, 2, 3, 5, ...
possForStep(n) == fibonacci(n+1)