代码随想录刷题Day38 | 509.斐波那契数 、70.爬楼梯 、746.使用最小花费爬楼梯
今日任务
509.斐波那契数
方法很简单,不讲
class Solution {
public:
int fib(int n) {
int F[31] = {0};
F[1] = 1;
for (int i = 2; i <= n; ++i) F[i] = F[i - 1] + F[i - 2];
return F[n];
}
};
或者省空间点的
class Solution {
public:
int fib(int n) {
if (!n) return 0;
int front = 0, rear = 1, tmp;
for (int i = 2; i <= n; ++i) {
tmp = rear;
rear = front + rear;
front = tmp;
}
return rear;
}
};
注意也可以用递归来做
class Solution {
public:
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
};
// time: O(n^2)
// space: O(n), 算上了编程语言中实现递归的系统栈所占空间
分析递归的时间复杂度直接画树形图即可,具体见文章:通过一道面试题目,讲一讲递归算法的时间复杂度!
70.爬楼梯
主要思想
- 设
dp[i]
表示到达第i阶有几种方法 - 那么到达 第
i
阶分两类方法- 可以从第
i - 1
阶跨一步(从1
阶到i - 1
阶有dp[i - 1]
种方法) - 可以从第
i - 2
阶跨两步(从1
阶到i - 2
阶有dp[i - 2]
种方法) - 综上,到 第
i
阶共有dp[i] = dp[i - 1] + dp[i - 2]
种方法
- 可以从第
- 而
dp[1] = 1
,dp[2] = 2
所以代码如下
class Solution {
public:
int climbStairs(int n) {
int dp[46] = {0};
dp[1] = 1, dp[2] = 2;
for (int i = 3; i <= n; ++i) dp[i] = dp[i - 1] + dp[i - 2];
return dp[n];
}
};
省空间版本
class Solution {
public:
int climbStairs(int n) {
int dp[3];
dp[1] = 1;
dp[2] = 2;
if (n < 3) return dp[n];
int sum;
for (int i = 3; i <= n; ++i) {
sum = dp[1] + dp[2];
dp[1] = dp[2];
dp[2] = sum;
}
return sum;
}
};
拓展
关于本题还可以继续深化,就是一步一个台阶、两个台阶、三个…一直到m个台阶,共有多少种方式爬到n阶
可以看看这道题目377. 组合总和 Ⅳ
746.使用最小花费爬楼梯
主要思想
dp[i]
表示从i
阶走的最少总花费- 由于每次可以跨一步或者跨两步,所以:
dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
- 由于到顶端需要从倒数第二或倒数第一个台阶走,所以返回
min(dp[n - 1], dp[n - 2])
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size(); // 本题n >= 2
vector<int> dp(n, 0);
// dp[i] 表示从i阶走的最少花费
dp[0] = cost[0];
dp[1] = cost[1];
for (int i = 2; i < n; ++i) dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
// 由于到顶端需要从倒数第二或倒数第一个台阶走,所以返回min(dp[n - 1], dp[n - 2]);
return min(dp[n - 1], dp[n - 2]);
}
};
省内存版本
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int dp0 = cost[0];
int dp1 = cost[1];
int tmp;
for (int i = 2; i < cost.size(); ++i) {
tmp = min(dp0, dp1) + cost[i];
dp0 = dp1; // 记录前两位
dp1 = tmp;
}
return min(dp0, dp1);
}
};