1. 程式人生 > 其它 >62. 不同路徑——動態規劃/排列組合

62. 不同路徑——動態規劃/排列組合

技術標籤:# LeetCode HOT 100動態規劃演算法c++資料結構python

1.題目

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

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

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

 

示例 1:


輸入:m = 3, n = 7
輸出:28
示例 2:

輸入:m = 3, n = 2
輸出:3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。
1. 向右 -> 向下 -> 向下
2. 向下 ->
向下 -> 向右 3. 向下 -> 向右 -> 向下 示例 3: 輸入:m = 7, n = 3 輸出:28 示例 4: 輸入:m = 3, n = 3 輸出:6 提示: 1 <= m, n <= 100 題目資料保證答案小於等於 2 * 109

2.自我思路及實現

3.總結思路及實現

動態規劃

設f(i,j)代表走到i,j處的所有路徑,那麼機器人或者向下到達i,j,或者向右到達i, j,那麼狀態轉移方程就是:
f (i , j) = f ( i − 1 , j ) + f ( i , j − 1)
上述方程i, j 不等於0

特例

  • 當i或 j = 0,時,只有一種路徑可以到達
  • f(0,0) = 1

優化:

  • 由於結果只與上一行和本行有關,因此可以建立一個一維陣列來儲存結果
  • cur[j] = cur[j - 1] + cur[j]
  • 未賦值之前右邊的cur[j] 始終表示當前行第i行的上一行第j列的值,賦值之後左邊的cur[j]表示當前行第i行第j列的值,cur[j-1] 表示當前行第i行第j-1列的值(cur[j-1] 在計算cur[j]之前就已經計算了,所以表示的是當前行而不是上一行

時間:mn
空間:min(m ,n)

class Solution {
    public int uniquePaths(int m, int n) {
        if(m > n)
return uniquePaths(n, m); int[] cur = new int[n]; Arrays.fill(cur, 1); for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { cur[j] += cur[j - 1]; } } return cur[n - 1]; } }

排列組合

無論哪種路徑,總是向下移動m - 1次,向右移動n-1次,那麼問題轉化為
m - 1個a與n - 1個b共有多少種排列方式 
根據排列組合計算,在 m - 1 + n - 1個位置中找m個位置將a放入,其餘位置填上b
C下(m - 1 + n - 1),上( m - 1) 或(n - 1)
在這裡插入圖片描述
化簡為在這裡插入圖片描述

為了防止乘法時越界,使用long儲存結果

時間:min(m, n),與迴圈次數有關,我們總可以選擇m為較小的數
空間:1

class Solution {
    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 - 1; x++, y++) {
            ans = ans * x / y;
        }
        return (int) ans;
    }
}

4.相關知識