【动态规划 && 斐波那切数列】LeetCode 746. Min Cost Climbing Stairs

LeetCode 746. Min Cost Climbing Stairs

本博客转载自:http://www.cnblogs.com/grandyang/p/8343874.html
存在无代价的最高层n层(顶层)
Solution1:
用动态规划Dynamic Programming来做。这里我们定义一个一维的dp数组,其中dp[i]表示爬到第i层的最小cost,然后我们来想dp[i]如何推导。我们来思考一下如何才能到第i层呢?是不是只有两种可能性,一个是从第i-2层上直接跳上来,一个是从第i-1层上跳上来。不会再有别的方法,所以我们的dp[i]只和前两层有关系,所以可以写做如下:
dp[i] = min(dp[i- 2] + cost[i - 2], dp[i - 1] + cost[i - 1])
最后我们返回最后一个数字dp[n]即可,参见代码如下:

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

Solution2:
再来看一种DP的解法,跟上面的解法很相近,不同在于dp数组长度为n,其中dp[i]表示到第i+1层的最小cost,分别初始化dp[0]和dp[1]为cost[0]和cost[1]。然后从i=2处开始遍历,此时我们的更新思路是,要爬当前的台阶,肯定需要加上当前的cost[i],那么我们还是要从前一层或者前两层的台阶上跳上来,那么我们选择dp值小的那个,所以递归式如下:
dp[i] = cost[i] + min(dp[i- 1], dp[i - 2])
最后我们在最后两个dp值中选择一个较小的返回即可,参见代码如下:

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

Solution3:
我们可以对空间复杂度进行优化,通过前面的分析我们可以发现,当前的dp值仅仅依赖前面两个的值,所以我们不必把整个dp数组都记录下来,只需用两个变量a和b来记录前两个值,然后不停的用新得到的值来覆盖它们就好了。我们初始化a和b均为0,然后遍历cost数组,首先将a和b中较小值加上num放入临时变量t中,然后把b赋给a,把t赋给b即可,参见代码如下:

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int a = 0, b = 0;
        for (int num : cost) {
            int t = min(a, b) + num;
            a = b;
            b = t;
        }
        return min(a, b);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值