2021-01-10

【C++】【leetcode】三步台阶问题

题目描述:有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
链接:https://leetcode-cn.com/problems/three-steps-problem-lcci

1.递归算法

2.非递归动态规划算法

3.非递归动态规划算法(优化空间)

 

解题思路:

         上图数组A用来存放相应台阶所对应的结果, A[i] 表示台阶数为 i 时能走通的方法个数。当n==8时,最后一次可以是跨一步两步三步。

当最后一次跨一步时,方法个数为A[7];当最后一次跨两步时,方法个数为A[6];当最后一次跨三步时,方法个数为A[5]。

        即得推导公式:A[i] = A[i-1] + A[i-2] + A[i-3]

       可以手动计算出A[1] = 1;A[2]=2;A[3]= 4,以下都可以利用推导公式得出。

1.递归算法: 容易想到,时间复杂度很大,只适合n很小的情况。

class Solution {
private:
    int Step(int n)
    {
        int result = 0;
        if (n<0)
            return 0;
        else if (n==0)
            return 1;
        else
        {
            result += Step(n-1);
            result += Step(n-2);
            result += Step(n-3);
            
            return result;
        }
    }
public:
    int waysToStep(int n) 
    {
        int result=0;
        result += Step(n-1);
        result += Step(n-2);
        result += Step(n-3);
        
        return result;
    }
};

2.非递归动态规划算法

class Solution {
    
public:
    int waysToStep(int n) 
    {
        unsigned int *result = new unsigned int[n];
        if (n==1)
            return 1;
        else if (n==2)
            return 2;
        else if (n==3)
            return 4;
        result[0] = 1;
        result[1] = 2;
        result[2] = 4;
        
        for (int i=3;i<n;++i)
            result[i] = (result[i-3]%1000000007+result[i-2]%1000000007+result[i-1]%1000000007)%1000000007;
        
        return result[n-1];
    }
};

3.非递归动态规划算法(优化空间),当n很大时会很费空间,其实只要4个元素就可以存储所有所需数值,将元素下标对4取模。

class Solution {
    
public:
    int waysToStep(int n) 
    {
        unsigned int *result = new unsigned int[4];
        if (n==1)
            return 1;
        else if (n==2)
            return 2;
        else if (n==3)
            return 4;
        result[0] = 1;
        result[1] = 2;
        result[2] = 4;
        
        for (int i=3;i<n;++i)
            result[i%4] = (result[(i-3)%4]%1000000007+result[(i-2)%4]%1000000007+result[(i-1)%4]%1000000007)%1000000007;
        
        return result[(n-1)%4];
    }
};

 

希望对你有所帮助

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值