1. 程式人生 > 實用技巧 >不同路徑

不同路徑

1.問題描述

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為“Finish”)。

問總共有多少條不同的路徑?

例如,上圖是一個7 x 3 的網格。有多少可能的路徑?

示例 1:

輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。

  1. 向右 -> 向右 -> 向下
  2. 向右 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向右

示例 2:

輸入: m = 7, n = 3
輸出: 28

提示:

  • 1 <= m, n <= 100
  • 題目資料保證答案小於等於 2 * 10 ^ 9

2.求解

排列組合

程式碼如下

    /*
    執行用時:0 ms, 在所有 Java 提交中擊敗了100.00% 的使用者
	記憶體消耗:35.1 MB, 在所有 Java 提交中擊敗了87.21% 的使用者
	*/
    public int uniquePaths(int m, int n) {
        if(m > n){
            return uniquePaths(n, m);
        }
        long ans = 1;
        for(int x = n, y = 1; y < m; x++, y++){
            ans = ans * x / y;
        }
        return (int) ans;
    }
  • 時間複雜度:O(min(m,n))

  • 空間複雜度:O(1)

動態規劃

  • 我們使用ij來表示從左上角走到(i, j)所走的步數,其中i < mj < n

  • 每次只能向下或者向右走一步,向下走一步那麼會從(i - 1, j)走來,向右走一步會從(i, j - 1)走來

    於是得出動態規劃方程

    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

  • 對於第一行 dp[0][j],或者第一列 dp[i][0],由於都是在邊界,所以只能為 1

程式碼如下

    /*
    執行用時:0 ms, 在所有 Java 提交中擊敗了100.00% 的使用者
	記憶體消耗:35.3 MB, 在所有 Java 提交中擊敗了71.93% 的使用者
	*/
	public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int i = 0; i < m; i++){
            dp[i][0] = 1;
        }
        for(int i = 0; i < n; i++){
            dp[0][i] = 1;
        }
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }
  • 時間複雜度、空間複雜度均為O(m * n)

使用滾動陣列優化的動態規劃