记录十三——爬楼梯

爬楼梯

一个n级的阶梯,每次只能爬一步或者两步,问有多少种爬法。


Input: 2
Output: 2
Explanation: There are two ways to climb to the top.

  1. 1 step + 1 step
  2. 2 steps

Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
3. 1 step + 1 step + 1 step
4. 1 step + 2 steps
5. 2 steps + 1 step


思路:因为只有两种可能,即爬一步或者爬两步,首先想到的就是递归,这种解法我想的是从0到n,阶梯逐级减少来进行递归,有点类似Fibonacci数列

class Solution {
    public int climbStairs(int n) {
        if(n == 1){
            return 1;
        }
        else if(n == 2){
            return 2;
        }
        else 
            return climbStairs(n - 1) + climbStairs(n - 2);
    }
}

时间复杂度:O(2n),空间复杂度:O(n)
在上面递归的基础上还可以对其进行优化,那就是增加一个记忆数组,避免重复的计算

class Solution {
    public int climbStairs(int n) {
        int[] memo = new int[n + 2];
        return climb(n,memo);
    }
    public int climb(int n,int[] memo){
        if(n == 1){
            return 1;
        }
        else if(n == 2){
            return 2;
        }
        else if(memo[n] > 0){
            return memo[n];
        }
        else{
            memo[n] = climb(n - 1,memo) + climb(n - 2,memo);
            return memo[n];
        }     
    }
}

时间复杂度:O(n),空间复杂度:O(n)
看了解析后,整理一下还有如下方法:
动态编程

public class Solution {
    public int climbStairs(int n) {
        if (n == 1) {
            return 1;
        }
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

时间复杂度:O(n),空间复杂度:O(n)。其实这种方法和我想的递归的思路本质上是一样的,只是将其转换成了数组来进行计算
Fibonacci数

public class Solution {
    public int climbStairs(int n) {
        if (n == 1) {
            return 1;
        }
        int first = 1;
        int second = 2;
        for (int i = 3; i <= n; i++) {
            int third = first + second;
            first = second;
            second = third;
        }
        return second;
    }
}

时间复杂度:O(n),空间复杂度:O(1)
将递归编程数的递归,省去了数组的空间,相应的减少了空间复杂度。

猜你喜欢

转载自blog.csdn.net/w1375834506/article/details/88684313