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);
}
};