Ways To reach the N-th Stairs| Climbing Stair Problem in Java

2025年5月5日 | 阅读5分钟

N级台阶问题,也称为爬楼梯问题。这是一个经典的动态规划挑战。该问题通常询问:给定一个楼梯,有多少种不同的方法可以爬到顶部? 如果你一次只能爬一级或两级台阶。

这个问题是循环、动态规划和迭代解法的一个应用示例。

问题解释

给定台阶数为 n

  • 如果你停留在第 0 级台阶,只有一种方法可以待在那里。
  • 如果 n = 1,则只有一条路可以到达顶部(走一步)。
  • 如果 n = 2,则有 2 种方法:(1+1) 或 (2)。

对于任何台阶 n > 2,爬到顶部的总方法数可以表示为

  1. 爬 n-1 级台阶的方法数。
  2. 爬 n-2 级台阶的方法数。

这种关系形成了递推关系

[f(n) = f(n-1) + f(n-2)]

方法一:递归解法

递归方法直接使用递推关系。

文件名:ClimbingStairs.java

输出

 
Ways to climb 5 stairs: 8   

解释

递归方法通过将问题分解为子问题来解决问题。每次调用都会迭代计算 f(n-1) 和 f(n-2)。然而,这种方法有一个显著的缺点:它会多次重新计算值,导致指数级的时间复杂度 (O(2^n))。

方法二:带备忘录的递归解法

为了提高递归的效率,使用备忘录可以存储先前计算的结果,避免重复计算。

文件名:ClimbingStairsMemoization.java

输出

 
Ways to climb 5 stairs: 8   

解释

此版本通过在 HashMap 中缓存结果来提高效率。对于每个 n,该 函数会检查结果是否已计算。它将时间复杂度降低到 (O(n)),而空间复杂度由于递归和备忘录存储而保持在 (O(n))。

方法三:动态规划(自底向上方法)

动态规划完全避免了递归,通过迭代地解决问题。

文件名:ClimbingStairsDP.java

输出

 
Ways to climb 5 stairs: 8   

解释

此方法使用一个 数组 dp,其中 dp[i] 表示爬 i 级台阶的方法数。从基本情况 (dp[0] 和 dp[1]) 开始,它迭代地构建解决方案。这降低了时间复杂度到 (O(n)),并避免了递归的开销。

方法四:带有空间优化的动态规划

上述 DP 解决方案使用了 (O(n)) 的空间。但由于每个 dp[i] 都依赖于前两个值 (dp[i-1] 和 dp[i-2]),我们可以将空间使用量减少到 (O(1))。

文件名:ClimbingStairsOptimized.java

输出

 
Ways to climb 5 stairs: 8   

解释

此解决方案不是存储所有中间值,而是只保留最后两个结果。这使得空间复杂度降低到 (O(1)),同时保持时间复杂度为 (O(n))。

方法五:矩阵快速幂

解决此问题的另一种高级方法是使用矩阵快速幂。关系 (f(n) = f(n-1) + f(n-2)) 可以表示为一个矩阵。

Ways To reach the N-th Stairs| Climbing Stair Problem in Java

通过使用 矩阵 快速幂,我们可以高效地以 (O(log n)) 的时间复杂度计算此值。

文件名:ClimbingStairsMatrix.java

输出

 
Ways to climb 5 stairs: 8   

解释

矩阵快速幂对于具有线性递推关系的问题非常高效。通过将变换矩阵提高到 (n-1) 次幂,我们可以在 (O(log n)) 时间内得到方法数。

结论

N级台阶问题是一个多用途的挑战,它凸显了计算机科学中各种解决问题技术的强大功能,特别是递归、动态规划和矩阵快速幂。虽然递归方法直观,但由于重复计算,其计算成本很高。

备忘录通过缓存结果提高了这一点,将时间复杂度降低到 (O(n))。迭代动态规划方法进一步优化了递归开销,而空间优化版本则将空间使用量减少到 (O(1))。

对于那些寻求更高效率的人来说,矩阵快速幂提供了对数时间复杂度,展示了数学洞察力在算法设计中的强大作用。每种方法都有其用例,具体取决于问题约束以及简洁性和效率之间的期望平衡。


下一主题ISBN号码 Java