题目描述:
三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
示例1:
输入:n = 3
输出:4
说明: 有四种走法
示例2:
输入:n = 5
输出:13
提示:
n范围在[1, 1000000]之间
个人思路:
爬楼梯问题,经典的动态规划问题,所以还是套用动态规划的模板即可。
- 状态定义:dp[i]表示到达阶梯i的走法个数。但通过转移方程的分析,我们不难发现,实际上当前dp[i]只和之前的三个dp值有关,我们duck不必保存所有的dp值,只需要用三个变量保存前三个值即可,即first = dp[i - 3],second = dp[i - 2],third = dp[i - 1]
- 初始化:我初始化的结果是1,1,2这里我添加了一个dp[0]=1的初始化结果表示第0个台阶也需要1步,当然这是不符合事实情况的,这里是为了将i=2即三层台阶时也统一成一个状态转移情况,当然也可以直接从第1个台阶开始,初始化为1,2,4。在很多动态规划题目中,通过添加一个不一定符合事实的初始化情况,可以简化一些判断条件。
- 状态转移:first, second, third = second, third, (first + second + third) % 1000000007。这道题目由于n的取值特别大,需要在状态转移时就通过取余来减小计算量,不然会超时。。。
具体代码如下:
class Solution:
def waysToStep(self, n: int) -> int:
if n <= 0:
return -1
if n <= 2:
return n
# 状态定义:dp[i]表示到达阶梯i的走法个数
# 由于本题状态方程只涉及到三个值,因此可以优化内存的使用
# first = dp[i - 3],second = dp[i - 2],third = dp[i - 1]
first = 1 # 添加一个dp[0]=1
second = 1
third = 2
for i in range(2, n):
first, second, third = second, third, (first + second + third) % 1000000007
return third