本文正在参加「Java主题月 - Java 刷题打卡」,详情查看<活动链接>
【Java 刷题打卡 】刷题比玩游戏好多了,成就感越来越强,每天坚持刷几道题,每天锻炼30分钟,等8块腹肌,等大厂offer.
那就干吧! 这个专栏都是刷的题目都是关于动态规划的,我会由浅入深、循序渐进,刷题就是这样需要连续不断的记忆--艾宾浩斯记忆法2121112。动态规划的内容不多,但是都是每个程序员必备的
什么题可以选择动态规划来做?
1.计数
- 有多少种方式走到右下角
- 有多少种方法选出k个数是的和是sum
2.求最大值最小值
- 从左上角走到右下角路径的最大数字和
- 最长上升子序列长度
3.求存在性
- 取石子游戏,先手是否必胜
- 能不能选出k个数使得和是sum
leecode 70 : 爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶 示例 2:
输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
看了之前的解题步骤,按部就班的来
2.1. 动态规划组成部分1:确定状态
简单的说,解动态规划的时候需要开一个数组,数组的每个元素f[i]或者f[i][j]代表什么,类似数学题中x, y, z代表什么
当然有些可以用滚动数组来优化,别被吓着了,这只是一个很简单的优化方法,稍后会讲到。
最后一步
如果看了前面机器人的题目,应该会猜到这种题解会是最后一步的情况相加。那么最后一步有哪些情况呢?
很明显,无非是爬一阶或者爬二阶。
因为有n个梯子,那么最后的情况为: n - 1 或者 n -2
子问题
对于子问题,就是计算最后一步前面的问题,如果我们计算出前面问题的结果并将之保存下来,我们求最后一步那不就迎刃而解啦
也就是说
子问题转化为: 我们设一共有k种方式爬到楼顶,那么
k = f(n) = f(n-1) + f(n-2)
k - 1 = f(n - 1) = f(n-2) + f(n-3)
...
2.2. 动态规划组成部分2:转移方程
对于任意n阶楼梯:
f(n) = f(n-1) + f(n-2)
2.3. 动态规划组成部分3:初始条件和边界情况
初始条件:n是一个正整数
我们是从第 0 级开始爬的,所以从第 0 级爬到第 0 级我们可以看作只有一种方案,即 f(0) = 1
从第 0 级爬到第 1 级我们可以也看作只有一种方案,即 f(1) = 1
3.4. 动态规划组成部分4:计算顺序
依此计算呗!
参考代码
JAVA版
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
接下来看看滚动数组怎么实现的吧
我们定义p 等价于 n-1, q 等价于 n-2 , r = 到达下一阶梯需要多少种方法 = p + q
初始条件不变r = 1, 代表从第0级到第0或第1级需要1次。
<----向左滚动
参考代码
JAVA版
public int climbStairs(int n) {
int p = 0, q = 0, r = 1;
for (int i = 1; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话
求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️