假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/climbing-stairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题:
解法参考自力扣(LeetCode)
解法1 暴力硬解
在某一阶楼梯上,下一步有两种走法:走1阶或者走2阶,如此反复,生成一棵递归树,则可以计算出所有方法的总数。
package climbing.stairs;
class Solution {
/**
* 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
* 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
* 注意:给定 n 是一个正整数。
* @param n 到达楼顶的阶数n
* @return 到达楼顶的方法总数
*/
public int climbStairs(int n) {
return climb(0, n);
}
/**
* 递归暴力硬解
* @param nNow 当前所在的阶梯数
* @param n 总阶梯数
* @return 当前阶梯到楼顶的爬楼梯方法总数
*/
public int climb(int nNow, int n) {
// 如果这一步之后当前阶数大于总阶数,由于最多跨出2阶,说明在迈出这一步之前处于n-1阶,此时只能走1阶,则跨出2阶是错误的,该步不计入总数
if (nNow > n) {
return 0;
}
// 如果这一步之后当前阶数等于总阶数,说明在迈出这一步之前处于n-1阶,此时只能走1步
if (nNow == n) {
return 1;
}
// 在处于某一阶时,可以有两种走法,一种是到达下1阶,一种是到达下2阶。
return climb(nNow+1, n) + climb(nNow+2, n);
}
}
可以预见,这样的解法消耗的时间是巨额的,果不其然,提交到leetCode的结果是超时:
解法2 斐波那契数列
反向来想,到达第i阶的方法有两种:在第i-1阶跨1阶到达,或者在第i-2阶跨2阶到达。设到达第i阶的方法为counter[i]
,则counter[i]=counter[i-1]+counter[i-2]
,则该题就变成了一道解斐波那契数列的题目,该数列的第一个数为1,第二个数为2。
package climbing.stairs;
/**
* @author focksor
*/
public class Solution {
/**
* 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
* 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
* 注意:给定 n 是一个正整数。
* @param n 到达楼顶的阶数n
* @return 到达楼顶的方法总数
*/
public int climbStairs(int n) {
if (n < 2) {
return n;
}
int a = 1;
int b = 2;
for (int i = 2; i < n; i++) {
if (a >= b) {
b += a;
} else {
a += b;
}
}
return a>=b?a:b;
}
}
结果:
本地测试代码
package climbing.stairs;
import org.junit.Assert;
import org.junit.Test;
/**
* @author focksor
*
* 示例 1:
* 输入: 2
* 输出: 2
* 解释: 有两种方法可以爬到楼顶。
* 1. 1 阶 + 1 阶
* 2. 2 阶
*
* 示例 2:
* 输入: 3
* 输出: 3
* 解释: 有三种方法可以爬到楼顶。
* 1. 1 阶 + 1 阶 + 1 阶
* 2. 1 阶 + 2 阶
* 3. 2 阶 + 1 阶
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/climbing-stairs
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class SolutionTest {
@Test
public void test() {
check(1, 1);
check(2, 2);
check(3, 3);
check(4, 5);
check(5, 8);
}
public void check(int n, int result) {
Solution solution = new Solution();
int solutionRes = solution.climbStairs(n);
Assert.assertEquals(result, solutionRes);
}
}