leetcode 746. Min Cost Climbing Stairs

这道题用动态规划解决。这道题乍一看,含义有点模糊。有两个点要搞清楚:1)给定len个台阶的梯子,其实是要爬完(越过)整个梯子才算到达顶部,相当于顶部是第len+1层台阶。台阶序号从0开始编号的话,顶部就是第len个台阶。2)从第i个台阶往上爬,才需要支付cost[i]。如果站在第i个台阶没有继续往上爬,则不需要支付const[i]。这样才好理解,dp[0]和dp[1]的值为什么是0。

第一版不带注释

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int len = cost.size();
        if(len < 3) return min(cost[0],cost[1]);
        vector<int> dp(len+1);
        dp[0] = 0;
        dp[1] = 0;
        for(int i = 2;i <= len;i++){
            dp[i] = min(cost[i-1]+dp[i-1],cost[i-2]+dp[i-2]);
        }
        return dp[len];
    }
};

写完注释后,发现当len等于2的情形,其实不需要单独考虑,后面的代码可以涵盖这种情况。

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int len = cost.size();
        //题目已经保证len>=2
        // if(len < 3) return min(cost[0],cost[1]);
        //给定的len层的梯子,楼顶其实是第len+1层
        vector<int> dp(len+1);//dp[i]表示到达第i层台阶所需要的最低花费
        dp[0] = 0;//含义是从第0层出发,爬0层就到达了第0层,不需要支付
        dp[1] = 0;//含义是从第1层出发,爬0层就到达了第1层,不需要支付
        //给定的len层的梯子,楼顶其实是第len+1层,但是由于从0开始编号,所以i应该取到len
        for(int i = 2;i <= len;i++){
            //到达第i层,有两种可能,要么是从第i-1层爬一个台阶到达的,
            //要么是从第i-2层爬两个台阶到达的
            dp[i] = min(cost[i-1]+dp[i-1],cost[i-2]+dp[i-2]);
        }
        return dp[len];
    }
};

进一步优化空间开销。因为计算dp[i]只需要dp[i-1]和dp[i-2],所以可以去掉dp数组,改用两个变量,如代码所示:

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int len = cost.size();
        //题目保证len>=2,所以下面的i从2开始起算
        int dp_i_2 = 0;//表示到达第i-2层所需的最小花费
        int dp_i_1 = 0;//表示到达第i-1层所需的最小花费
        int dp_i = 0;  //表示到达第i层所需要的最小花费
        for(int i = 2;i <= len;i++){
            dp_i = min(dp_i_1+cost[i-1],dp_i_2+cost[i-2]);
            dp_i_2 = dp_i_1;
            dp_i_1 = dp_i;
        }
        return dp_i;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值