动态规划之爬楼梯|Go主题月

4,787 阅读3分钟

【Golang主题学习月】周末肝了几道动态规划题,发了一个超细腻的教学版,反响很不错哦,接下来我会使用两种语言进行编码刷题,分别是GO和JAVA,各位菁英们,坚持刷题吧。

😄

如果你对动态规划不熟悉,望转到该篇 \color{red}{如果你对动态规划不熟悉,望转到该篇~}

肝了好多天-动态规划十连-超细腻解析|刷题打卡

什么题可以选择动态规划来做?

1.计数

  • 有多少种方式走到右下角
  • 有多少种方法选出k个数是的和是sum

2.求最大值最小值

  • 从左上角走到右下角路径的最大数字和
  • 最长上升子序列长度

3.求存在性

  • 取石子游戏,先手是否必胜
  • 能不能选出k个数使得和是sum

leecode 70 : 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以12个 \color{red}{爬 1 或 2 个~}台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶 示例 2:

输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 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次。

image.png

<----向左滚动

image.png

参考代码

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…,更多内容陆续奉上。