小u走楼梯问题题解

76 阅读3分钟

题目描述

小U最近决定挑战一座非常高的楼梯,每次他可以选择走一步或两步,但有一个重要的限制:他不能连续走两步。因此,小U想知道他总共有多少种不同的方式可以从楼梯的底部走到顶端。

题解思路

这个问题可以使用动态规划来解决。由于小U不能连续走两步,我们需要在状态转移过程中考虑前一步的状态。我们可以定义两个状态:到达某一级楼梯时,最后一步是走一步或两步。

动态规划的状态定义

  1. dp[i][0] 表示到达第 i 级楼梯,并且最后一步是走一步的走法总数。
  2. dp[i][1] 表示到达第 i 级楼梯,并且最后一步是走两步的走法总数。

状态转移方程

为了确保我们不会连续走两步,我们需要分别计算最后一步是走一步或两步的走法:

  • 如果小U最后一步走一步,那么在第 i 级楼梯的走法数量为 dp[i][0] = dp[i-1][1],因为前一步必须是走两步。
  • 如果小U最后一步走两步,那么在第 i 级楼梯的走法数量为 dp[i][1] = dp[i-2][0],因为前两步必须是走一步。

初始化

我们需要初始化前两个楼梯的状态:

  • dp[0][0] = 1,表示在第0级楼梯的唯一一种方式是站在原地。
  • dp[0][1] = 0,因为没有走两步到达第0级楼梯的情况。
  • dp[1][0] = 1,表示从第0级楼梯走一步到达第1级楼梯的唯一方式。
  • dp[1][1] = 0,因为无法从第0级楼梯直接走两步到达第1级楼梯。

总走法

到达第 n 级楼梯的总走法为 dp[n][0] + dp[n][1]

代码实现

以下是完整的Java代码实现:

java

public class StaircaseChallenge {
    public static void main(String[] args) {
        int n = 10;  // 示例楼梯层数
        System.out.println("不同走法的总数: " + countWays(n));
    }

    public static int countWays(int n) {
        if (n == 0) return 1;
        if (n == 1) return 1;

        int[][] dp = new int[n + 1][2];
        dp[0][0] = 1;
        dp[0][1] = 0;
        dp[1][0] = 1;
        dp[1][1] = 0;

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

        return dp[n][0] + dp[n][1];
    }
}

代码解释

  1. 初始化

    • 对于第0层和第1层,分别初始化dp数组的值。初始状态下,从第0层到第0层和第1层的走法数量分别为1。
  2. 状态转移

    • 通过遍历每一层,根据最后一步是走一步还是走两步,更新dp数组。
    • dp[i][0]表示最后一步是走一步的情况,等于前一层最后一步是走两步的走法数量。
    • dp[i][1]表示最后一步是走两步的情况,等于前两层最后一步是走一步的走法数量。
  3. 计算结果

    • 返回到达第n层的总走法数量,即dp[n][0] + dp[n][1]

复杂度分析

时间复杂度

由于我们只需要遍历一次楼梯的所有层数,每一层只进行常数时间的计算,因此时间复杂度为O(n)

空间复杂度

使用了一个二维数组dp来存储中间状态,因此空间复杂度为O(n)

总结

通过动态规划的方法,我们可以有效地计算出在给定楼梯层数下,小U有多少种不同的走法。这种方法不仅考虑了不能连续走两步的限制,同时通过状态转移方程确保了计算的准确性和效率。