Python-回溯法(爬楼梯)

本文通过解析LeetCode中的经典爬楼梯问题,详细介绍了如何使用回溯法求解所有可能的行走方案,深入理解回溯算法的工作原理。

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

问题:n阶楼梯,每次只能走一步或两步,输出所有方案

LeetCode有这道题不过是输出方案数,采用递归的方法,为了加深对回溯法了解,此处使用回溯法。

'''爬楼梯'''
n = 7 # 楼梯阶数
x = []  # 一个解(长度不固定,1-2数组,表示该步走的台阶数)
X = []  # 一组解
def climb_stairs(k): # 走第k步
  global n, x, X
  if sum(x) == n: # 已走的所有步数之和等于楼梯总台阶数
    print(x)
  else:
    for i in [1, 2]: # 第k步这个元素的状态空间为[1,2]
      x.append(i)
      if sum(x)<=n: # 剪枝
        # print(x)
        climb_stairs(k+1)
      x.pop()       # 回溯
# 测试
climb_stairs(0) # 走第0步

输出结果:

[1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 2]
[1, 1, 1, 1, 2, 1]
[1, 1, 1, 2, 1, 1]
[1, 1, 1, 2, 2]
[1, 1, 2, 1, 1, 1]
[1, 1, 2, 1, 2]
[1, 1, 2, 2, 1]
[1, 2, 1, 1, 1, 1]
[1, 2, 1, 1, 2]
[1, 2, 1, 2, 1]
[1, 2, 2, 1, 1]
[1, 2, 2, 2]
[2, 1, 1, 1, 1, 1]
[2, 1, 1, 1, 2]
[2, 1, 1, 2, 1]
[2, 1, 2, 1, 1]
[2, 1, 2, 2]
[2, 2, 1, 1, 1]
[2, 2, 1, 2]
[2, 2, 2, 1]
 

### 使用深度优先搜索(DFS)和回溯算法实现最小花费爬楼梯问题 #### 定义问题 最小花费爬楼梯问题是寻找一条路径使得从地面到达顶层所消耗的成本最低。这个问题可以通过动态规划来高效解决,但是也可以通过深度优先搜索(DFS)配合回溯的方法来进行探索。 #### 设计递归函数 为了使用DFS解决问题,设计一个递归函数`dfs(index, current_cost)`用于遍历所有可能的走法并记录当前累积成本。这里`index`表示当前位置索引而`current_cost`代表走到该位置为止累计产生的费用。 对于每一个节点有两个选择:要么从前一阶跳过来(`cost[index-1]`),要么前两阶直接跨上来(`cost[index-2]`)。因此,在每次调用时都需要考虑这两种情况,并更新相应的开销。 当达到数组末端或者超出范围的时候停止递归,并比较最终得到的不同路线总代价选出其中较小者作为最优解。 考虑到性能优化方面的需求,则可以在过程中加入记忆化技术——即利用缓存存储已经计算过的结果以避免重复运算相同的子结构[^2]。 下面是具体的Python代码实现: ```python def minCostClimbingStairs(cost): memo = {} # 创建字典用来储存已知的最佳结果 def dfs(index, accumulated_cost=0): nonlocal memo if index >= len(cost): return accumulated_cost if index in memo: return memo[index] one_step = dfs(index + 1, accumulated_cost + cost[index]) two_steps = dfs(index + 2, accumulated_cost + cost[index]) optimal_choice = min(one_step, two_steps) memo[index] = optimal_choice return optimal_choice start_from_0th_or_1st = min(dfs(0), dfs(1)) return start_from_0th_or_1st ``` 此方法虽然能够正确得出答案,但由于其本质上的暴力穷举特性以及缺乏剪枝机制,所以在面对较大输入规模的数据集时效率较低。相比之下,基于动态规划的方式则更加简洁有效。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值