【Golang主题学习月】周末肝了几道动态规划题,发了一个超细腻的教学版,反响很不错哦,接下来我会使用两种语言进行编码刷题,分别是GO和JAVA,各位菁英们,坚持刷题吧。
😄
什么题可以选择动态规划来做?
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:计算顺序
依此计算呗!
参考代码
GO语言版
func climbStairs(n int) int {
dp := make([]int, n+1)
dp[0] = 1
dp[1] = 1
for i := 2; i <= n; i++ {
dp[i] = dp[i-1] + dp[i-2]
}
return dp[n]
}
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次。
<----向左滚动
参考代码
GO语言版
func climbStairs1(n int) int {
p := 0
q := 0
r := 1
for i := 1; i <= n; i++ {
p = q
q = r
r = p + q
}
return r
}
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;
}
❤️❤️❤️❤️
非常感谢人才们能看到这里,如果这个文章写得还不错,觉得有点东西的话 求点赞👍 求关注❤️ 求分享👥 对暖男我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !
文末福利,最近整理一份面试资料《Java面试通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:GitHub github.com/Tingyu-Note…,更多内容陆续奉上。