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

本文介绍了解决LeetCode746.爬楼梯最小成本问题的三种方法,包括动态规划的一维数组实现、优化后的固定长度动态规划数组实现及进一步的空间优化方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
    }
};
### 用Python实现斐波那契数列 斐波那契数列是一种经典的数学数列,其定义为:第0项为0,第1项为1,从第2项开始,每一项等于前两项之和。在Python中,可以通过多种方法实现该数列的计算,以下是几种常见的实现方式。 #### 方法一:递归法 递归法是最直接的方式,但效率较低,时间复杂度为 \(O(2^n)\)。代码如下: ```python def fibonacci_recursive(n): if n == 0: return 0 elif n == 1: return 1 else: return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2) # 示例 n = 10 print([fibonacci_recursive(i) for i in range(n)]) ``` 这种方法虽然简洁,但由于大量的重复计算,对于较大的 \(n\) 不适用[^1]。 #### 方法二:迭代法 迭代法通过循环计算每一项值,时间复杂度为 \(O(n)\),空间复杂度为 \(O(1)\)。代码如下: ```python def fibonacci_iterative(n): if n == 0: return 0 a, b = 0, 1 for _ in range(1, n): a, b = b, a + b return b # 示例 n = 10 print([fibonacci_iterative(i) for i in range(n)]) ``` 此方法避免了递归带来的栈溢出问题,同时减少了不必要的重复计算[^2]。 #### 方法三:矩阵快速幂法 矩阵快速幂法利用斐波那契数列的矩阵形式进行加速计算,时间复杂度为 \(O(\log n)\)。代码如下: ```python import numpy as np def fibonacci_matrix(n): if n == 0: return 0 F = np.array([[1, 1], [1, 0]], dtype=object) result = np.linalg.matrix_power(F, n - 1) return result[0, 0] # 示例 n = 10 print([fibonacci_matrix(i) for i in range(n)]) ``` 这种方法适用于需要高效计算大数的情况,但实现较为复杂[^1]。 #### 方法四:动态规划动态规划法通过保存中间结果来减少重复计算,时间复杂度为 \(O(n)\),空间复杂度为 \(O(n)\)。代码如下: ```python def fibonacci_dp(n): if n == 0: return 0 dp = [0] * (n + 1) dp[1] = 1 for i in range(2, n + 1): dp[i] = dp[i - 1] + dp[i - 2] return dp[n] # 示例 n = 10 print([fibonacci_dp(i) for i in range(n)]) ``` 这种方法适合需要多次查询不同位置值的场景[^4]。 ### 总结 以上介绍了四种实现斐波那契数列的方法,各有优缺点。选择具体实现时需根据实际需求权衡效率与实现复杂度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值