Python 算法快闪 LeetCode 编号 70 - 爬楼梯

目录

题目描述

[【计时开始 - 15分钟】](#【计时开始 - 15分钟】)

【比赛结束】

快闪赛的亮点


如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

题目描述

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1: 输入:n = 2 输出:2 解释:有兩種方法可以爬到樓頂。

  1. 1 阶 + 1 阶
  2. 2 阶

示例 2: 输入:n = 3 输出:3 解释:有三种方法可以爬到樓頂。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶

提示: 1 <= n <= 45


【计时开始 - 15分钟】

思考过程与执行(内部模拟):

0-2 分钟:理解题目,识别模式

  • "爬楼梯",每次 1 或 2 步。求总方法数。
  • n=1: 1 种 (1)
  • n=2: 2 种 (1+1, 2)
  • n=3: 3 种 (1+1+1, 1+2, 2+1)
  • n=4: 5 种 (1+1+1+1, 1+1+2, 1+2+1, 2+1+1, 2+2)
  • 这个序列:1, 2, 3, 5... 看起来像斐波那契数列!
  • 递推关系 :到达第 i 阶的方法数 F(i) = F(i-1) (从 i-1 阶爬 1 步上来) + F(i-2) (从 i-2 阶爬 2 步上来)。
  • 边界条件:F(1) = 1, F(2) = 2。

2-7 分钟:选择算法与实现

  • 递归 (Naive)

def climbStairs_recursive(n):

if n == 1: return 1

if n == 2: return 2

return climbStairs_recursive(n-1) + climbStairs_recursive(n-2)

  • 问题:重复计算严重,O(2^n) 时间复杂度,对于 n=45 会超时。
  • 递归 + 记忆化搜索 (Memoization)

memo = {}

def climbStairs_memo(n):

if n in memo: return memon

if n == 1: return 1

if n == 2: return 2

result = climbStairs_memo(n-1) + climbStairs_memo(n-2)

memon = result

return result

  • 复杂度:O(n) 时间,O(n) 空间。可行。
  • 动态规划 (Bottom-up)
    • 基于斐波那契数列的迭代计算。
    • 思路:从 F(1) 和 F(2) 开始,迭代计算 F(3), F(4), ..., F(n)。
    • 时间复杂度:O(n)。
    • 空间复杂度:O(n)(如果用数组存储),或者 O(1)(只存储前两项)。
    • 工程落地:O(1) 空间复杂度更优。

选择动态规划 (Bottom-up, O(1) space) 作为最终方案。

7-12 分钟:编写代码(Python)

class Solution:

def climbStairs(self, n: int) -> int:

"""

爬楼梯问题:求到达 n 阶楼顶的不同方法数。

每次可爬 1 或 2 阶。

这是一个斐波那契数列的变种问题。

F(n) = F(n-1) + F(n-2)

边界条件: F(1) = 1, F(2) = 2

"""

处理基本边界情况

if n == 1:

return 1

if n == 2:

return 2

使用动态规划,O(1) 空间复杂度

a, b 分别代表 F(i-2) 和 F(i-1)

a = 1 # 对应 F(1)

b = 2 # 对应 F(2)

从第 3 阶开始迭代计算

for i in range(3, n + 1):

当前阶数的方法数 = 前一阶 + 前两阶

current_ways = a + b

更新 a 和 b,为下一轮计算做准备

a = b # 原来的 F(i-1) 变成 F(i-2)

b = current_ways # 新计算出的 F(i) 变成 F(i-1)

return b # 最终 b 存储的就是 F(n)

12-14 分钟:简单测试与注释

  • 示例 1:n = 2
    • 代码直接返回 2。正确。
  • 示例 2:n = 3
    • a = 1, b = 2
    • i = 3: current_ways = 1 + 2 = 3. a = 2, b = 3.
    • 循环结束,返回 b (3)。正确。
  • 考虑 n=1:代码已处理。
  • 代码风格 :变量命名 a, b 稍显简略,但符合动态规划的惯例。current_ways 提升了可读性。注释解释了思路和边界条件。
  • 工程落地:代码逻辑清晰,边界条件处理到位。

14-15 分钟:最终检查

  • 代码是否满足 LeetCode 格式要求? (类 Solution,方法 climbStairs) -> 是。
  • 是否包含了思路说明? -> 是,在函数注释中。
  • 通过示例测试? -> 是。
  • 时间复杂度 O(n),空间复杂度 O(1)。符合要求。

【比赛结束】

最终提交(模拟):

解题思路: 该问题是典型的斐波那契数列变种。到达第 n 阶的方法数等于到达第 n-1 阶的方法数(再走一步)加上到达第 n-2 阶的方法数(再走两步)。定义 F(i) 为到达第 i 阶的方法数。 递推关系为:F(i) = F(i-1) + F(i-2)。 基本边界条件: F(1) = 1 (只能走 1 步) F(2) = 2 (走 1+1 或 2)

采用动态规划(迭代法)实现,使用 O(1) 的空间复杂度来存储前两项的结果,并向前迭代计算直到 n

代码:

class Solution:

def climbStairs(self, n: int) -> int:

"""

爬楼梯问题:求到达 n 阶楼顶的不同方法数。

每次可爬 1 或 2 阶。

这是一个斐波那契数列的变种问题。

F(n) = F(n-1) + F(n-2)

边界条件: F(1) = 1, F(2) = 2

"""

处理基本边界情况

if n == 1:

return 1

if n == 2:

return 2

使用动态规划,O(1) 空间复杂度

a, b 分别代表 F(i-2) 和 F(i-1)

a = 1 # 对应 F(1)

b = 2 # 对应 F(2)

从第 3 阶开始迭代计算

for i in range(3, n + 1):

当前阶数的方法数 = 前一阶 + 前两阶

current_ways = a + b

更新 a 和 b,为下一轮计算做准备

a = b # 原来的 F(i-1) 变成 F(i-2)

b = current_ways # 新计算出的 F(i) 变成 F(i-1)

return b # 最终 b 存储的就是 F(n)

快闪赛的亮点

  • 思维速度:题目模式识别(斐波那契)非常快,直接跳过了暴力递归,选择了高效的 DP 方法。
  • 工程落地
    • 选择了空间复杂度更优的 O(1) DP 实现。
    • 代码注释清晰,解释了思路、递推关系和边界条件。
    • 边界条件 n=1, n=2 处理得很直接。
    • 变量命名(a, b)虽然简洁,但注释解释了其含义,在 DP 中是常见且可接受的。
  • 时间控制:在 15 分钟内完成了从理解到编写、测试的完整流程。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
geovindu2 分钟前
python: Generators Pattern
开发语言·python·设计模式·生成器模式
没有不重的名么3 分钟前
spyder使用教程
开发语言·python
阿正的梦工坊4 分钟前
【Rust】06-函数、控制流与模块组织
开发语言·算法·rust
Wonderful U4 分钟前
Python+Django实战|线上问卷与投票调研系统:自定义题型、问卷发布、链接分享、答卷收集、数据可视化、报表导出
python·信息可视化·django
阿正的梦工坊10 分钟前
【Rust】16-async/await、Future 与执行器模型
网络·算法·rust
Cloud_Shy61813 分钟前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 36 - 39)
开发语言·人工智能·笔记·python
阿正的梦工坊14 分钟前
【Rust】11-Rust 所有权模型的编译期推理机制
开发语言·算法·rust
zmzb010314 分钟前
Python课后习题训练记录Day128
开发语言·python
AIFQuant15 分钟前
全球行情自动更新、多品种展示、性能优化实战指南
python·性能优化·金融·node.js·restful
风筝在晴天搁浅17 分钟前
LeetCode CodeTop 88.合并两个有序数组
算法·leetcode·职场和发展