【动态规划】LeetCode-面试题08.01三步问题

算法那些事专栏说明:这是一个记录刷题日常的专栏,每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目,在这立下Flag
个人主页:Jammingpro
专栏链接:算法那些事
每日学习一点点,技术累计看得见

题目

题目描述

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

执行示例

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

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

提示

n范围在[1, 1000000]之间

题解

由题目可知,爬到第1个台阶的方法数为1种,即从起始处爬1步到达;爬到第2个台阶的方法数有2种,即从开始处爬2步到达或从第1个台阶爬1步到达;爬到第3个台阶的方法数有4种,即从开始处爬3步到达、从第1个台阶爬2步到达或从第2个台阶爬1步到达…即,求爬到第n个台阶的方法数就等于将到达第n个台阶前的3个台阶的方法数相加,从而得到状态转移方程为 f ( n ) = f ( n − 1 ) + f ( n − 2 ) + f ( n − 3 ) f(n)=f(n-1)+f(n-2)+f(n-3) f(n)=f(n1)+f(n2)+f(n3)。上面已经知道到达第1到3号台阶的方法数,再通过状态转移方程就可以求出第4号台阶及以后台阶的方法数。实现代码如下↓↓↓

class Solution {
public:
    int waysToStep(int n) {
        if(n == 1) return 1;
        if(n == 2) return 2;
        const int MOD = 1000000007;
        vector<int>dp(n);
        dp[0] = 1;
        dp[1] = 2;
        dp[2] = 4;
        for(int i = 3; i < n; i++)
            dp[i] = ((dp[i - 1] + dp[i - 2]) % MOD + dp[i - 3]) % MOD;
        return dp[n - 1];
    }
};

上面算法的时空复杂度均为O(N),我们可以使用滚动数组的方式,将空间复杂度优化为O(1)。我们可以设置四个变量mostpreppreprecur,分别表示到达n-3、n-2、n-1和n号台阶的方法数。初始状态下,mostpre、ppre、pre、cur分别初始化为1、2、4、7,即到达第1-4号台阶的方法数。通过mostpre=ppreppre=prepre=cur操作,此时mostpre、ppre、pre分别保存到达第2、3、4号台阶的方法数,再通过cur=mostpre+ppre+pre可计算出第5号台阶的方法数。以此类推,可求出到达后续台阶的方法数,实现代码如下↓↓↓

class Solution {
public:
    int waysToStep(int n) {
        const int MOD = 1000000007;
        if(n == 1) return 1;
        if(n == 2) return 2;
        if(n == 3) return 4;
        int mostpre = 1, ppre = 2, pre = 4, cur = 7;
        for(int i = 4; i < n; i++)
        {
            mostpre = ppre;
            ppre = pre;
            pre = cur;
            cur = ((mostpre + ppre) % MOD + pre) % MOD;
        }
        return cur;
    }
};

本文存在不足,欢迎留言或私信批评、指正。希望我的解决方法能够对你有所帮助~~
今日打卡完成,点亮小星星☆→★

你可能感兴趣的:(算法那些事,动态规划,leetcode,算法)