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];
}
};
本文来自博客园,作者:曼路的个人博客,转载请注明原文链接:https://www.cnblogs.com/manlujun/p/15612138.html