LeetCode刷题Easy篇爬楼梯问题(递归和动态规划问题)

题目

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

Example 1:

Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

Example 2:

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

我的尝试

感觉是个递归问题,但是没有设计出递归方程,无法利用递归求解,也无法转化为动态规划问题。关键步骤没有搞定,后来看了一下思路,明白了状态转化方程,

求到达n的方式有几种,如果我们知道到达n-1有几种方式,到达n-2有几种方式,那么相加就是到达n有几种方式,因为这两个方案没有交集。n-1到n只能走一步,n-2到n走两步,如果后者走1+1这种方式,那么跟前者是重叠到。所以这两个方案没有交集。

来,尝试递归和DP解法解决这个题目。

递归思路

递归思路:

1. 转化方程或者说递归方式,理解: 1和2是基本单元,如果是5,利用基本单元可以分为(1,4),(2,3),因此递归方程就是

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

2. 递归终止条件,如果n=1,返回1,如果n=2,则有两种可能,返回2(2,和1,1)

3 递归时间复杂度较高,递归方式在leetcode测试test case正常,但是会超时,一般递归方程写出来后,可以考虑利用DP方式解决。

class Solution {
    public int climbStairs(int n) {
        if(n==1){
            return 1;
        }
        //写在一起,如果输入2,返回1,不对,明确基本单元结果,明确状态转化方程,递归的核心
        if(n==2){
            return 2;
        }
        return climbStairs(n-1)+climbStairs(n-2);
        
    }
}

动态规划方法

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

其实就是个斐波那契数列问题,梳理后另一个写法,思路一样:

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

节省空间的方法,最优方法:

class Solution {
    public int climbStairs(int n) {
        if(n==1) return 1;
        if(n==2) return 2;
        int one_stair=1;
        int two_stair=2;
        int ways=0;
        for (int i = 3; i <=n; i++) {
            ways=one_stair+two_stair;
            one_stair=two_stair;
            two_stair=ways;
           
        }
        return ways;
        
        
    }
}

猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/84305249