這兩天要幫老師錄製一下題解視頻,所以題目挑簡單一點的,減(shui)輕(liang)大(pian)家(wen)壓(zhang)力。
題目鏈接
LeetCode 面試題 08.01. 三步問題[1]
題目描述
三步問題。有個小孩正在上樓梯,樓梯有 階臺階,小孩一次可以上 階、 階或 階。實現一種方法,計算小孩有多少種上樓梯的方式。結果可能很大,你需要對結果模 。
示例1
輸入:
n = 3
輸出:
4
解釋:
有四種走法
示例2
輸入:
n = 5
輸出:
13
題解
這道題是動態規劃入門題,我相信大家都會做,如果不會做,那就當我沒說過這句話。
令 爲上 個臺階的方案數,那麼最後一步可以是跳 步,或者跳 步,或者跳 步過去的,所以就有:
初始情況就是 。
然後利用取模的加法公式,可以每算出一個 都取一下模。
當然了這題太水了,我主要就是想看看大家會怎麼實現呢?
代碼
定義長度爲 的數組
最樸素的方法當然是定義長度爲 的數組,然後算就完事了,代碼如下:
typedef long long ll;
const ll p = 1e9+7;
const int N = 1e6+10;
class Solution {
public:
ll f[N] = {1, 2, 4};
int waysToStep(int n) {
for (int i = 3; i < n; ++i) {
f[i] = (f[i-1] + f[i-2] + f[i-3]) % p;
}
return f[n-1];
}
};
定義四個變量
但是這樣太費空間了啊,其實每次只需要用到之前的三個狀態就行了,然後還要用個臨時變量用來交換狀態值,代碼如下:
typedef long long ll;
const ll p = 1e9+7;
class Solution {
public:
int waysToStep(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
if (n == 3) return 4;
ll a = 1, b = 2, c = 4, d;
for (int i = 3; i < n; ++i) {
d = (a + b + c) % p;
a = b;
b = c;
c = d;
}
return d;
}
};
定義長度爲 的數組
但是用 個變量也太醜陋了,對於我這種處女座患者(對不起我是射手座)來說,完全無法忍受!
所以我直接定義了一個長度爲 的數組,然後下標對 取模來實現循環數組,這樣代碼看起來就很舒服啦:
typedef long long ll;
const ll p = 1e9+7;
class Solution {
public:
int waysToStep(int n) {
ll f[3] = {1, 2, 4};
for (int i = 3; i < n; ++i) {
(f[i%3] += f[(i-1)%3] + f[(i-2)%3]) %= p;
}
return f[(n-1)%3];
}
};
應讀者要求,再來個 python
代碼:
class Solution:
def waysToStep(self, n: int) -> int:
f = [1, 2, 4]
for i in range(3, n):
f[i%3] += f[(i-1)%3] + f[(i-2)%3]
f[i%3] %= 1e9+7;
return int(f[(n-1)%3])
參考資料
[1]
LeetCode 面試題 08.01. 三步問題: https://leetcode-cn.com/problems/three-steps-problem-lcci/