Fork me on GitHub

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
posted @ 2020-11-02 14:50  龙城飞将军  阅读(147)  评论(0编辑  收藏  举报