Leetcode记录-面试题 08.01. 三步问题
1. 面试题 08.01. 三步问题
三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
- 示例1:
输入:n = 3
输出:4
说明: 有四种走法
示例2:
输入:n = 5
输出:13
1.1. 问题分析
1.1.1. 深度遍历
数组[1,2,3]求排列,当n=4时,有[[1,1,1],[1,2],[2,1],[3]]四种,即循环搜索[1,2,3]集合,当取出的元素总和等于n时,递归结束。再通过一个hash表去重,最后hash表的长度即解的数量
1.1.1.1. 代码实现
private void dfs(int[] arr, int n, Stack<Integer> path, Map<String, Integer> maps) {
for (int m : arr) {
path.add(m);
int tmp = sum(path);
if (tmp == n) {
maps.put(toString2(path), 1);
} else if (tmp > n) {
path.pop();
break;
} else if (tmp < n) {
dfs(arr, n, path, maps);
}
path.pop();
}
}
- 空间复杂度,hash表是额外的空间,
- 时间复杂度,递归1次进行3次遍历,O(2^n)
1.1.2. 数学解法-找规律
该问题属于爬台阶的变种,走到第i级台阶时,有三种办法可以走到。从i-1级走1级到达;从i-2级台阶走2级到达;从i-3级走3级到达。故有:f(i)=f(i-1)+f(i-2)+f(i-3);
1.1.2.1. 实现
if (n == 1) {
return 1;
} else if (n == 2) {
return 2;
} else if (n == 3) {
return 4;
} else {
long[] dp = new long[n + 1];
dp[1] = 1;
dp[2] = 2;
dp[3] = 4;
for (int i = 4; i <= n; i++) {
dp[i] = (dp[i - 1] +dp[i - 2] + dp[i - 3])%1000000007;
System.out.println(i+" "+dp[i]);
}
return (int)dp[n];
}
- 空间复杂度,O(n)
- 时间复杂度,一次遍历O(n)
1.2. 输出样例:
n | output |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
4 | 7 |
20 | 121415 |
30 | 53798080 |
61 | 752119970 |