2.三步问题(easy)

1.题目链接:

面试题 08.01. 三步问题 - 力扣(LeetCode)面试题 08.01. 三步问题 - 三步问题。有个小孩正在上楼梯,楼梯有 n 阶台阶,小孩一次可以上 1 阶、2 阶或 3 阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模 1000000007。示例 1: 输入:n = 3 输出:4 说明:有四种走法示例 2: 输入:n = 5 输出:13提示: 1. n 范围在[1, 1000000]之间https://leetcode.cn/problems/three-steps-problem-lcci/description/2.题目描述:

三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方    法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。​(1e7)

示例1:​
 输入:n = 3 ​
 输出:4​
 说明: 有四种走法​

示例2:​
 输入:n = 5​
 输出:13​

提示:​
n范围在[1, 1000000]之间​

3. 解法(动态规划)

算法思路

1. 状态表示

这道题可以根据「经验 + 题目要求」直接定义出状态表示:​dp[i]  表示:到达 i  位置时,一共有多少种方法。​

2. 状态转移方程

以 i 位置状态的最近的一步,来分情况讨论:​
如果dp[i] 表示小孩上第 i  阶楼梯的所有方式,那么它应该等于所有上一步的方式之和:

  1. i.上一步上一级台阶,dp[i] += dp[i - 1]
  2. ii. 上一步上两级台阶,dp[i] += dp[i - 2]
  3. iii. 上一步上三级台阶,dp[i] += dp[i - 3]

综上所述,dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]

需要注意的是,这道题目说,由于结果可能很大,需要对结果取模。

在计算的时候,三个值全部加起来再取模,即 (dp[i - 1] + dp[i - 2] + dp[i - 3]) % MOD  是不可取的,同学们可以试验一下,n  取题目范围内最大值时,网站会报错 signedinteger overflow 对于这类需要取模的问题,我们每计算一次(两个数相加/乘等),都需要取一次模。否则,万一发生了溢出,我们的答案就错了。

3. 初始化
从我们的递推公式可以看出,dp[i]  在 i = 0, i = 1  以及 i = 2  的时候是没有办法进行推导的,因为 dp[-3]dp[-2]  或 dp[-1]  不是一个有效的数据。​因此我们需要在填表之前,将 1, 2, 3  位置的值初始化。​
根据题意,dp[1] = 1, dp[2] = 2, dp[3] = 4

4. 填表顺序

毫无疑问是「从左往右」。

5. 返回值
         应该返回 dp[n]  的值。

Java算法代码:

class Solution {
    public int waysToStep(int n) {
        // 1.创建dp表
        // 2.初始化
        // 3.填表
        // 4.返回值

        int MOD = (int)1e9+7;
        if(n == 1 || n==2) return n;
        if(n == 3) return 4;
        int[] dp = new int[n+1];
        dp[1] = 1; dp[2]=2;dp[3]=4;
        for(int i =4;i<=n;i++)
        dp[i]=((dp[i-1]+dp[i-2])%MOD+dp[i-3])%MOD;
        return dp[n];
    }
}

运行结果:

动态规划:动态规划: 这道题目给定很多,状态的定义dp[i],以及状态转移方程dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3],初始化dp[1] = 1,dp[2] = 2,dp[3] = 4 。填表顺序(左 --> 右,以及返回值dp[n]。

---------------------------------------------------------------------------------------------------------------------------------

记住要做的几件事:

1.状态定义

2.状态转移方程

3.初始化

4.填表顺序

5.返回值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值