图解推导爬楼梯(跳台阶)问题详细过程

编程入门 行业动态 更新时间:2024-10-26 12:22:04

图解推导爬楼梯(<a href=https://www.elefans.com/category/jswz/34/1768659.html style=跳台阶)问题详细过程"/>

图解推导爬楼梯(跳台阶)问题详细过程

1,题目:

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

2,递推公式(状态转移方程)推导

分析,需求比较简单。拿到这个题目的第一想法就是递归,但是这个递推公式是怎么得来的?我居然陷入了逻辑死胡同,花了很长时间才彻底绕出来了。

不多说,先上图:

图片链接:上楼梯(1次上1台或者2台)问题 | ProcessOn免费在线作图,在线流程图,在线思维导图 |

认真的看上图,可以看出:

上到第1台台阶:
一共有1种方法:即: f(1) = 1

上到第2台台阶:
一共有f(2)种方法:即: f(2) = 2。其实这里也是 f(2) = f(1)的方法上网上走一台,在加另外一种方法,直接从地面迈2台台阶,有就是 f(2) = f(1) +1

上到第3台台阶:
1,先上到第1台,用了f(1)种方法,然后直接跨2步到第3台,用了的方法数还是f(1)
2,先上到第2台,用了f(2)种方法,然后直接跨1步到第3台,用了的方法数还是f(2)
因此方法数为: f(3) = f(1) + f(2)

上到第4台台阶:
1,先上到第2台,用了f(2)种方法,然后直接跨2步到第4台,用了的方法数还是f(2)
2,先上到第3台,用了f(3)种方法,然后直接跨1步到第4台,用了的方法数还是f(3)
因此方法数为: f(4) = f(4-2) + f(4-1)

上到第5台台阶:
1,先上到第3台,用了f(3)种方法,然后直接跨2步到第5台,用了的方法数还是f(3)
2,先上到第4台,用了f(4)种方法,然后直接跨1步到第5台,用了的方法数还是f(4)
因此方法数为: f(5) = f(5-2) + f(5-1)

上到第n台台阶:
1,先上到第n-2台,用了f(n-2)种方法,然后直接跨2步到第n台,用了的方法数还是f(n-2)
2,先上到第n-1台,用了f(n-1)种方法,然后直接跨1步到第n台,用了的方法数还是f(n-1)
因此方法数为: f(n) = f(n-2) + f(n-1)

因此,递推公式是: f(n) = f(n-2) + f(n-1)

我一开始的时候理解成了:

从第 n - 2台台阶上去的时候,还要迈一次(2台),从n-1上到n的时候,还要迈一次(1台),因此错误的认为,总方法数是 f(n) = [f(n-2) +2 ]+  [f(n-1) + 1],将方法和迈的步数搞混了。

从f(n-2)台阶迈到n台台阶(这里只能一次迈2台,否则会重复为f(n-1) ),走到f(n-2)的每一种方法再都迈一次2台台阶到达n台台阶,此时用的方法数还是f(n-2)种。同理,走到f(n-1)的每一种方法再都迈一次1台台阶到达n台台阶,此时用的方法数还是f(n-1)种。走到第n台台阶,只可能从n-2台上来,或者从n-1上来。所以,正确的递推公式是:  f(n) = f(n-2) + f(n-1)

有了递推公式代码就好写了:

3,递归+备忘录求解

/*** 递归方式求解求爬n台台阶的总方法数* 递推公式,方法总数: f(n) = f(n-2) + f(n-1)* @param {*} n * @returns 爬n台台阶的总方法数*/
function climbStairs(n) {const cache = new Map()/*** 内部递归方法,递归方式求解爬n台台阶的所有方法数* @param {*} n * @returns */function climb(n) {if(n === 0) return 0if(n === 1) return 1if(n === 2) return 2// 使用备忘录缓存const cachedN = cache.get(n)if(cachedN !== undefined) {return cachedN}const result = climb(n-2) + climb(n-1)cache.set(n, result) // 存入缓存return result        }return climb(n)
}

4,动态规划求解

有了递推公式,状态转移方程也就很容易写了:

dp[n] =  dp[n-2] + dp[n-1]; dp[0] = 0|1; dp[1] = 1; dp[2] = 2;

/*** 动态规划方式求解,从底(小)向上解* 时间复杂度: O(n)* 空间复杂度: O(n)* 最核心的步骤也是状态转移方程,跟递归的递推公式差不多* dp[n] =  dp[n-2] + dp[n-1]; dp[0] = 0|1; dp[1] = 1; dp[2] = 2;* @param {*} n 要上的总台阶数* @returns 爬n台台阶的总方法数*/
function climbStairsDP(n) {const dp = []dp[0] = 0dp[1] = 1dp[2] = 2for(let i=3; i<=n; i++) {dp[i] = dp[i-1] + dp[i-2]}return dp[n]
}

5,优化的动态规划版本求解

/*** 动态规划方式求解爬楼梯问题,从底(小)向上解。基于上面的方法优化状态记录,从数组状态记录优化为三个变量,优化存储空间* 时间复杂度: O(n)* 空间复杂度: O(1)* 原状态: dp[n] =  dp[n-2] + dp[n-1]; dp[0] = 0|1; dp[1] = 1; dp[2] = 2;* 压缩为: next = pre + current; pre = 1, current = 2, next; pre、current、next滚动更新* @param {*} n 要上的总台阶数* @returns 爬n台台阶的总方法数*/
function climbStairsDP2(n) {let pre = 1, current = 2, next; //将数组状态滑动为三个变量状态for(let i=3; i<=n; i++) {next = pre + current// 滑动更新变量状态pre = currentcurrent = next}return next
}

更多推荐

图解推导爬楼梯(跳台阶)问题详细过程

本文发布于:2023-06-29 10:54:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/943761.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:跳台   爬楼梯   过程   详细

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!