leetcode 面试题 08.01. 三步问题

题目

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

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

输入:n = 5
输出:13
提示:

n范围在[1, 1000000]之间

思路

  1. 状态转移式的分析
台阶 方案数 说明
0 0 无意义
1 1 仅有一次上一个台阶这中方法
2 2 0→2(1)或者1→2(1)
3 4 0→3(1)或者1→3(1)或者2→3(2)
4 7 1→4(1)或者2→4(2)或者3→4(4)
  1. 确定状态转移方程
    • 一次可以上1阶、2阶或3阶,有三种跨法,以每种跨法最后的一步来划分(直接到达目标台阶),那么在要上第n(n>=3)阶的时候,可以从n-3阶上、可以从n-2阶上,也可以从n-1阶上(以所求状态最近的一步来划分问题
    • 从n-3阶上的时候,只用从n-3直接跨3阶到n,此跨法的方案数就等同于从0阶到第n-3阶的方案数
    • 同理,从n-2阶上的时候,只用从n-2直接跨2阶到n,方案数等同于从0阶到第n-2阶的方案数;从n-1阶上的时候,只用从n-1直接跨1阶到n,方案数等同于从0阶到第n-1阶的方案数。
    • 那么总的方案数就等于以上3种情况之和
    • 建立一维dp数组,index对应台阶数,value对应从0到i台阶的方案数。那么到达第 i 个台阶时,则有dp[i] = dp[i - 3] + dp[i - 2] + dp[i - 1]
  2. 初始化
    保障填dp[]表的时候不越界
  3. 填表
    确定填表顺序,保障目标位置需求的数据已经处理完毕
    根据动态转移方程,填表顺序应为从左往右
  4. 确定返回值
    到达第n号台阶,即dp[n],要访问到第n个位置,那么dp[]表的大小应该为n+1

代码

class Solution {
    public int waysToStep(int n) {
        if (n == 0 || n == 1 || n == 2) return n;   //2.初始化
        if (n == 3) return 4;
        int MOD = (int)1e9 + 7;
        
        int[] dp = new int[n +1];   //1.创建dp表
        
        dp[0] = 0;    //2.初始化
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 4;
        for (int i = 4;i <= n;i ++){   //3.填表
            dp[i] = ((dp[i - 1] + dp[i - 2])%MOD + dp[i - 3])%MOD;
        }

        return dp[n];  //4.确定返回值
    }
}

你可能感兴趣的:(刷题,leetcode,动态规划,算法)