面试题 08.01. 三步问题

原题链接:

https://leetcode-cn.com/problems/three-steps-problem-lcci/

题目描述

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

示例1:

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

示例2:

输入:n = 5
输出:13

提示:

  • n范围在[1, 1000000]之间

动态规划思想

1.确定状态(两个核心:1最后一步 2化成子问题)
2转移方程
3开始和边界条件
4计算顺序

思路:

还剩最后一步时,有三种情况,走1个台阶,走2个台阶,走3个台阶(n>=3);
由此得出转移方程:f(n)=f(n-1)+f(n-2)+f(n-3),(n>=3)
n=1:只能走一阶,共一种方法;
n=2:可以走两个一阶或者一个两阶,共两种方法;
n=3:可以走三个一阶或者先一个一阶后一个两阶或者先一个两阶后一个一阶或者一个三阶,共四种方法。

C语言代码(超时):

int waysToStep(int n){
    long long sum=0;
    if(n==1) return 1;
    else if(n==2) return 2;
    else if(n==3) return 4;
    else return (waysToStep(n-1)+waysToStep(n-2)+waysToStep(n-3))%1000000007;
}

超时分析:
采用了自顶向下的思路递归,从最大的原问题f(n)开始向下逐渐分解规模,直到f(1)和f(2)底层,然后逐层返回答案,每一项都要重复计算,耗时较大;

AC代码:

int waysToStep(int n){
    long long a[1000000],i;
    if (n < 4) {
        return n == 3 ? 4 : n;
    }
    a[1]=1;
    a[2]=2;
    a[3]=4;
    for(i=4;i<=n;i++){
    	a[i]=(a[i-1]+a[i-2]+a[i-3])%1000000007;
	}
    return a[i-1];
}

采用数组存取每一步计算出来的结果,内存消耗大。

对空间进一步优化代码:

int waysToStep(int n){
    long long sum,a,b,c,i;
    if (n < 4) {
        return n == 3 ? 4 : n;
    }
    a=1;
    b=2;
    c=4;
    for(i=4;i<=n;i++){
    	sum=(a+b+c)%1000000007;
        a=b;
        b=c;
        c=sum;
	}
    return sum;
}

定义少量的变量循环使用,消耗内存小。
思路:
后两种方法均采用自底向上的动态规划思想,从规模最小的f(1)和f(2)开始往上推,直到得出我们想要的f(n),每一次迭代都包含前面子问题中计算出来的结果,无重复计算!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WTY2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值