代码随想录day38| 509. 斐波那契数 、70. 爬楼梯 、746. 使用最小花费爬楼梯

本文介绍了斐波那契数列、爬楼梯问题以及最小花费爬楼梯问题的动态规划解决方案,包括确定dp数组含义、递推公式、初始化步骤和遍历顺序。

动规五部曲:

——确定dp[i]含义

递推公式

dp数组如何初始化

遍历顺序

打印dp数组

509. 斐波那契数

dp[i]:第i个的斐波拉契数

递推公式:等于dp[i-2]+dp[i-1]

dp数组的初始化:dp[0] = 0,dp[1]=1

遍历顺序:从前向后

int fib(int n){
    if(n <= 1){
        return n;
    }
    int* dp = (int*)malloc(sizeof(int)*(n + 1));

    dp[0] = 0;
    dp[1] = 1;

    int i;
    for(i = 2; i <= n; ++i){
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n];
}

70. 爬楼梯

dp[i]到达第i阶有dp[i]种方法

递推公式:dp[i-2]+dp[i-1]——因为有两种方法可以上楼梯,所以第上第i阶时应该是走到第i-2阶的方法加上第i-1阶的方法

dp数组的初始化:dp[0] = 0,dp[1]=1

遍历顺序:从前向后

int climbStairs(int n) {
    if(n <= 2)
        return n;
    
    int* dp = (int*)malloc(sizeof(int)*(n + 1));
    dp[0] = 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];
}

746. 使用最小花费爬楼梯

dp[i]:到达第i阶花费最小力气dp[i]

递归公式:dp[i] = fmin(dp[i-1] + cost[i-1], dp[i-2] +cost[1-2])

初始化:dp[0] = dp[1] = 0 ——可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯,所以说0和1是初始化为0

遍历顺序:从前向后 

#include <math.h>
int minCostClimbingStairs(int *cost, int costSize) {
  int dp[costSize + 1];
  dp[0] = dp[1] = 0;
  for (int i = 2; i <= costSize; i++) {
    dp[i] = fmin(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1]);
  }
  return dp[costSize];
}

<think>我们被要求回答LeetCode70题“爬楼梯”的解题思路,重点在动态规划和递归方法。根据引用内容,我们可以总结如下:1.问题描述:爬楼梯,每次可以爬1或2个台阶,到达第n阶有多少种不同的方法。2.动态规划是解决此问题的典型方法,状态转移方程为:dp[i]=dp[i-1]+dp[i-2]。3.递归方法虽然直观,但存在重复计算,可能导致超时,可以使用记忆化搜索优化(Top-DownDP)。4.动态规划(自底向上)通常使用组存储中间结果,然后进行空间优化(例如用两个变量代替组)。我们将按照以下结构组织回答:一、问题描述二、思路分析(递归关系)三、递归方法(及优化)四、动态规划方法(及优化)五、总结同时,根据要求,我们需要在回答末尾生成相关问题。注意:所有学表达式(包括变量、方程)使用$...$格式,独立公式使用$$...$$格式。回答使用中文。引用标识:在引用的内容末尾添加[^1]、[^2]等,但注意我们引用的内容来自用户提供的引用[1]到[4]。</think>### LeetCode 70爬楼梯|动态规划与递归解析 #### 一、问题描述 给定楼梯阶 $n$,每次可爬 $1$ 或 $2$ 阶,求到达第 $n$ 阶的不同方法总。 #### 二、核心思路 **状态转移方程**: $$ dp[i] = dp[i-1] + dp[i-2] $$ 其中 $dp[i]$ 表示到达第 $i$ 阶的方法。该方程源于:第 $i$ 阶只能从 $i-1$ 阶(爬 $1$ 阶)或 $i-2$ 阶(爬 $2$ 阶)到达[^2][^4]。 --- #### 三、动态规划解法(推荐) **自底向上迭代**,避免递归重复计算: ```python def climbStairs(n: int) -> int: if n <= 2: return n # 边界处理 dp = [0] * (n+1) dp[1], dp[2] = 1, 2 # 初始状态 for i in range(3, n+1): dp[i] = dp[i-1] + dp[i-2] # 状态转移 return dp[n] ``` **空间优化**(滚动变量): 仅需存储前两个状态,空间复杂度优化至 $O(1)$: ```python def climbStairs(n: int) -> int: if n <= 2: return n a, b = 1, 2 # a=dp[i-2], b=dp[i-1] for _ in range(3, n+1): a, b = b, a + b # 更新状态 return b ``` --- #### 四、递归解法(需优化) **基础递归**(不推荐): 直接实现状态方程,但存在指级重复计算: ```python def climbStairs(n: int) -> int: if n == 1: return 1 if n == 2: return 2 return climbStairs(n-1) + climbStairs(n-2) # 递归分解 ``` **问题**:计算 $dp[5]$ 需重复计算 $dp[3]$ 和 $dp[4]$,时间复杂度 $O(2^n)$,$n=45$ 时超时[^3]。 **优化:记忆化搜索(Top-Down DP)** 添加缓存避免重复计算,时间复杂度降为 $O(n)$: ```python def climbStairs(n: int) -> int: memo = {} # 记忆字典 def dfs(k): if k <= 2: return k if k not in memo: memo[k] = dfs(k-1) + dfs(k-2) # 缓存结果 return memo[k] return dfs(n) ``` --- #### 五、复杂度对比 | 方法 | 时间复杂度 | 空间复杂度 | 适用性 | |---------------|------------|------------|----------------| | 基础递归 | $O(2^n)$ | $O(n)$ | 仅小 $n$ | | 记忆化搜索 | $O(n)$ | $O(n)$ | 需额外缓存 | | 动态规划 | $O(n)$ | $O(n)$ | 通用 | | **空间优化DP**| $O(n)$ | $O(1)$ | **最优解** | > **总结**:动态规划(尤其空间优化版)是本题最佳解法。其本质是斐波那契列问题,状态转移方程 $dp[i]=dp[i-1]+dp[i-2]$ 是核心[^1][^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值