1. 程式人生 > 實用技巧 >Leetcode記錄-面試題 08.01. 三步問題

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