题目
题目链接:leetcode-cn.com/leetbook/re…
题解
1、根据动态规划理论分析
1、划分子问题,确定子问题边界,将问题的求解变成多步判断的过程;
问题概述:每次爬 1 个或 2 个台阶,有多少种不同的方法,即求最多有多少种方法;
-
如果只有 1 个台阶,那么只有一种方法,即爬一个台阶;
-
如果有 2 个台阶,那么可以一次就爬 2 个台阶,或者分开两次爬,第一次爬一个台阶,后面就变成了爬 1 个台阶的问题;
-
如果有 3 个台阶,第一步可以爬一个台阶,然后就变成了爬 2 个台阶的问题;第一步可以爬两个台阶,然后就变成了爬 1 个台阶的问题;
2、定义优化函数和列出递归方程
根据上面的递归方程可知,其满足优化原则;
3、编程
以下是编程实现;
2、递归实现
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
if(0 === n) {
return 0;
}else if(1 === n) {
return 1;
}else if(2 === n) {
return 2;
}
return climbStairs(n-1) + climbStairs(n-2);
};
在 leetcode 的编译器中运行时显示超出时间限制,原因是因为子问题需重复计算,这造成了极大的时间浪费;
那么改善思路是和以往一致的,空间换时间,将每个子问题的结果记录下来,以便求解同样的子问题是直接使用结果;
下面的迭代实现就是使用这样的思路;
3、迭代实现
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
if(0 === n) {
return 0;
}else if(1 === n) {
return 1;
}else if(2 === n) {
return 2;
}
// 记录子问题的解的数组
let results = [0,1,2],
result = 0;
for(let i = 3;i <= n;i++) {
result = results[i - 1] + results[i - 2];
results[i] = result;
}
return result;
};
上面的迭代实现算法的空间复杂度为 O(n),当空间资源稀缺时,可以想办法将空间复杂度减少到常量级;
可以根据递归方程知道,问题规模为 n 的问题只需要使用规模为 n-1 的子问题和规模为 n-2 的子问题的解;
以下是只用两个变量来记录子问题的解的算法;
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function(n) {
if(0 === n) {
return 0;
}else if(1 === n) {
return 1;
}else if(2 === n) {
return 2;
}
// 只用两个变量来记录子问题的解
let r1 = 1,
r2 = 2,
result = 0;
for(let i = 3;i <= n;i++) {
result = r1 + r2;
r1 = r2;
r2 = result;
}
return result;
};
大家如果有更好的思路和解法,欢迎大家一起来讨论啊~
这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里: