leetcode刷题之动态规划法NO.2

1.题目

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。

2.思路

2.1.读题

  • n阶才能到
  • 每次只能爬1或2阶
  • 未知量是爬到n阶的方法数

2.2.分析

  • 首先明确该题目含有最优子结构,因此可以使用动态规划算法。
  • 其次,解决动态规划问题的时候,第一就是明确状态,那么什么是状态呢?状态就是子问题的解,因此找到子问题,状态就浮现出来了。对于这个题,状态就是爬上x阶,用到的方法数f(x)。
  • 然后,第二点就是找出状态转移方程,那么什么是状态转移方程呢?状态转移方程就是状态之间的转换方程。对于该问题来讲,x阶的前一个状态由于选择的不同,是x-1阶或x-2阶。因此状态转移方程就是f(x) = f(x-1) + f(x-2)。

3.实现

实现有多种方式,第一种就是直接用递归,但是算法复杂度太高;第二种就是带记忆的递归;第三种是带DP的递推。此外,还有好多方法,比如使用数学公式、矩阵幂等。

3.1.递归方法

class Solution {
public:
    int climbStairs(int n) {
       if (n == 0) return 1;
       if (n == 1) return 1;

       return climbStairs(n-2) + climbStairs(n-2); 
    }
};

3.2.带记忆的递归方法

class Solution {
public:
    int climbStairs(int n) {
       if (n == 0) return 1;
       if (n == 1) return 1;
       vector<int> mem(n+1, 0);   
   
       return helper(mem, n);
    }
	
    int helper(vector<int> &mem, int n) {
    mem[0] = 1;
    mem[1] = 1;
	
    if (mem[n] != 0) return mem[n];
    mem[n] = helper(mem, n-2) + helper(mem, n-1);
	
    return mem[n];
    }
};

3.3.递推法

class Solution {
public:
    int climbStairs(int n) {
       if (n == 0) return 1;
       if (n == 1) return 1;
	   
       vector<int> dp(n+1, 0);
       dp[0] = dp[1] = 1;
       for (int i=2; i<=n; i++) {
	   dp[i] = dp[i-1] + dp[i-2];
       }
	   
       return dp[i];
    }
};
posted @ 2021-11-27 15:51  曼路的个人博客  阅读(40)  评论(0编辑  收藏  举报