解题思路:动态规划
具体思路:
首先处理边界情况,当 n 小于等于 1 时直接返回 n,接着创建一个长度为 n+1 的动态规划数组dp,用于存储每一步计算出的斐波那契数,先初始化 dp[0] = 0 和 dp[1] = 1 这两个基础值,最后通过循环从 2 遍历到 n,依次计算每个位置的 dp[i],即dp[i] = dp[i - 1] + dp[i - 2],最终返回dp[n]得到第 n 项的结果。
具体代码:
cpp
class Solution {
public:
int fib(int n) {
if (n <= 1) return n;
vector<int> dp(n + 1);
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++){
dp[i] = dp[i -1] + dp[i - 2];
}
return dp[n];
}
};
时间复杂度:O(n)
空间复杂度:O(n)
由于计算第 n 项仅依赖前两项的结果,无需存储完整的 dp 数组,因此仅用长度为 2 的数组 dp 来保存最近两项的值,每次计算当前项为前两项之和sum = dp[0] + dp[1],再更新 dp 数组,可进一步优化空间复杂度。
具体代码:
cpp
class Solution {
public:
int fib(int n) {
if (n <= 1) return n;
int dp[2];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++){
int sum = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
时间复杂度:O(n)
空间复杂度:O(1)
解题思路:动态规划
具体思路:
首先处理边界情况,当 n ≤ 1 时直接返回 n,接着创建长度为 n+1 的动态规划数组 dp,用于存储到达每一阶台阶的方法数,先初始化 dp[1] = 1 爬 1 阶只有 1 种方法,dp[2] = 2 爬 2 阶有两种方法,由于到达第 i 阶的方法数等于到达第 i - 1 阶再爬 1 阶和第 i - 2 阶再爬 2 阶的方法数之和,因此通过循环从 3 遍历到 n,依次计算dp[i] = dp[i - 1] + dp[i - 2],最终返回dp[n]得到到达第 n 阶台阶的总方法数。
具体代码:
cpp
class Solution {
public:
int climbStairs(int n) {
if (n <= 1) return n;
vector<int> dp(n + 1);
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
};
时间复杂度:O(n)
空间复杂度:O(n)
由于计算到达第 n 阶的方法数仅依赖前两阶的结果,无需存储完整的 dp 数组,因此仅用长度为 3 的数组dp,实际仅使用 dp[1] 和 dp[2] 两个位置,每次计算当前阶的方法数为前两阶之和sum = dp[1] + dp[2],再更新 dp 数组,可进一步优化空间复杂度。
具体代码:
cpp
class Solution {
public:
int climbStairs(int n) {
if (n <= 1) return n;
int dp[3];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
int sum = dp[1] + dp[2];
dp[1] = dp[2];
dp[2] = sum;
}
return dp[2];
}
};
时间复杂度:O(n)
空间复杂度:O(1)
解题思路:动态规划
具体思路:
首先获取台阶花n费数组 cost 的长度 n,创建长度为 n + 1 的动态规划数组 dp,其中 dp[i] 表示到达第 i 个台阶的最小花费,初始化 dp[0] = 0,dp[1] = 0,因为题目允许从第 0 阶或第 1 阶开始爬,初始无花费,随后从 2 循环到 n,由于到达第 i 阶的最小花费只能由两种方式得到,从第 i - 1 阶爬 1 阶加上第 i - 1 阶的花费或从第 i - 2 阶爬 2 阶加上第 i - 2 阶的花费),因此取两者中的较小值作为 dp[i],即dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]),最终返回 dp[n],即为到达楼顶的最小总花费。
具体代码:
cpp
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
vector<int> dp(n + 1);
dp[0] = 0;
dp[1] = 0;
for (int i = 2; i <= cost.size(); i++) {
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[n];
}
};
时间复杂度:O(n)
空间复杂度:O(n)
由于计算到达第 i 阶的最小花费仅依赖前两阶 i - 1 和 i - 2 阶的结果,无需存储完整的 dp 数组,因此仅用长度为 2 的数组 dp 保存前两阶的最小花费,计算当前阶的最小花费取从 i - 2 阶爬 2 阶 dp[0] + cost[i - 2]和从 i - 1 阶爬 1 阶dp[1] + cost[i - 1]两种方式的最小值,再更新 dp 数组,可进一步优化空间复杂度。
具体代码:
cpp
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
int dp[2];
dp[0] = 0;
dp[1] = 0;
for (int i = 2; i <=n; i++) {
int sum = min(dp[0] + cost[i - 2], dp[1] + cost[i - 1]);
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
时间复杂度:O(n)
空间复杂度:O(1)