70. 爬楼梯

在这里插入图片描述
dp,先给前两个台阶初始化,从3跳到n。这里我们直接省略空间复杂度,因为只要记录当前台阶的前两个台阶的方法数即可,不用开数组了,容易写错的是,因为我们要将当前台阶赋给下面一个,下一个赋给下两个,顺序千万不能错,要先将下一个赋给下两个才行

class Solution {
public:
    int climbStairs(int n) {
        //dp即可,记录前一个台阶有几种方法能到达
        if(n <= 2) return n;
        int lastTwo = 1, lastOne = 2;
        int res = 0;
        for(int i = 3; i <= n; ++i){//从3跳到n
            res = lastOne+lastTwo;
            lastTwo = lastOne;
            lastOne = res;
        } 
        return res;
    }
};

翻车了,如果<=2直接返回n,两个数字记录当前台阶的前两节。从第三节开始跳(是先计算第三节有几种方法),状态转移方程是前两节的方法和,记得更新前两节,前两节变为前一节,前一节变为当前。

class Solution {
public:
    int climbStairs(int n) {
        //dp[i]存的是第i级台阶有几种方法跳上
        //初始化,dp[0] = 1,dp[1]=1
        //状态转移方程,dp[i] = dp[i-1]+dp[i-2]
        //因为只要记录前两个,所以不用dp数组了
        if(n <= 2) return n;
        int pre2 = 1, pre1 = 2;//分别是前2个和前一个
        int res = 0;
        //直接从3开始跳
        for(int i = 3; i <= n; ++i){
            res = pre1 + pre2;
            pre2 = pre1;
            //要的就是更新完的值
            pre1 = res;
        }
        return res;
    }
};

递归也很简单,来一个值记录当前第几级就行,更新pre的顺序别弄错

class Solution {
public:
    int dfs(int pre1, int pre2,int cur, int n){
        if(cur == n){
            return pre1 + pre2;
        }
        return dfs(pre2,pre1+pre2,cur+1,n);
    }
    int climbStairs(int n) {
        //dp含义:dp[n]记录的是爬到第n个台阶有几种方法
        //转移方程:dp[n] = dp[n-1]+dp[n-2],因为n-2有一种方法跳上来,n-1也有一种方法跳上来,所以dp[n] = dp[n-1]*1 + dp[n-2]*1
        //记得初始化
        if(n <= 3) return n;
        //压缩一下,只要记录前两节台阶就行
        int pre1 = 1, pre2 = 2;
        // int res = 0;
        // for(int i = 3; i <= n; ++i){
        //     res = pre1+pre2;
        //     pre1 = pre2;
        //     pre2 = res;
        // }


        return dfs(pre1,pre2,3,n);
    }
};
class Solution {
public:
    int dfs(int pre1, int pre2, int tmp ,int n){
        if(tmp == n) return pre1+pre2;
        return dfs(pre2,pre1+pre2,tmp+1,n);
    }
    int climbStairs(int n) {
        //迭代,用dp[i]记录跳上当前台阶有几种方法
        //状态转移:dp[i] = dp[i-1]*1+dp[i-2]*1
        //basecase:dp[1] = 1,dp[2] = 1,因为只要前两个状态可以进行状压
        if(n <= 2) return n;
        // int pre1 = 1, pre2 = 2;
        // int res = 0;
        // for(int i = 3; i <= n; ++i){
        //     res = pre1+pre2;
        //     pre1 = pre2;
        //     pre2 = res;
        // }
        // return res;

        //dfs就是在内部计算每一级台阶有几种方法跳上
        return dfs(1,2,3,n);

        //或者自顶向下递归,用记忆化搜索,但是记忆化搜索就要线性空间复杂度了
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值