使用js实现变态跳台阶
/**
* 变态跳台阶问题:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
*
* @param {number} n 台阶数
* @returns {number} 跳法总数
*/
function jumpFloor(n) {
// 特殊情况处理:0级或1级台阶
if (n <= 1) {
return 1;
}
// 动态规划:dp[i] 表示跳上 i 级台阶的跳法总数
// dp[i] = dp[i-1] + dp[i-2] + ... + dp[0] (i > 1)
// 进一步简化:dp[i] = 2 * dp[i-1]
// 或者更直接的数学公式:dp[i] = 2^(i-1)
// 方法一:迭代法 (推荐,效率更高)
// let dp = [1, 1]; // 初始化 dp[0] 和 dp[1]
// for (let i = 2; i <= n; i++) {
// dp[i] = 2 * dp[i-1];
// }
// return dp[n];
// 方法二:递归法 (简洁,但n较大时可能栈溢出)
// if (n <= 1) {
// return 1;
// } else {
// return 2 * jumpFloor(n - 1);
// }
// 方法三:数学公式法 (最简洁高效)
return Math.pow(2, n - 1);
}
// 测试用例
console.log(jumpFloor(0)); // 输出 1
console.log(jumpFloor(1)); // 输出 1
console.log(jumpFloor(2)); // 输出 2
console.log(jumpFloor(3)); // 输出 4
console.log(jumpFloor(4)); // 输出 8
console.log(jumpFloor(10)); // 输出 512
解题思路和代码解释:
这个问题本质上是一个数学问题,可以找到规律并用公式直接计算。
-
递推关系: 跳上
n
级台阶,最后一步可以跳 1 级,2 级,...,n 级。因此,跳上n
级台阶的跳法总数等于跳上n-1
级、n-2
级、...、0 级台阶的跳法总数之和。 -
简化递推关系: 可以发现
dp[i] = dp[i-1] + dp[i-2] + ... + dp[0]
。而dp[i-1] = dp[i-2] + dp[i-3] + ... + dp[0]
。因此,dp[i] = dp[i-1] + dp[i-1] = 2 * dp[i-1]
。 -
数学公式: 最终可以推导出
dp[n] = 2^(n-1)
。
代码中提供了三种实现方法:
- 迭代法: 使用数组
dp
存储中间结果,避免重复计算,效率较高,推荐使用。 - 递归法: 代码简洁,但当
n
较大时,可能会导致栈溢出。 - 数学公式法: 最简洁高效的方法,直接使用公式计算结果。
根据实际情况选择合适的方法,一般情况下,迭代法或数学公式法是更优的选择。 如果n
的值非常大,Math.pow(2, n - 1)
也可能会超出 JavaScript Number 类型的最大值,这时需要考虑使用 BigInt 来处理。