示例 1:
輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右
示例 2:
輸入: m = 7, n = 3 輸出: 28
下面我們先說用遞歸如何解決此題:
/** * * @param m * @param n * @return * * 遞歸方法:根據題意我們可以分析得出,計F(m,n)為到達橫坐標為m,縱坐標為n的路徑數,則 * F(m,n) = F(m-1,n) + F(m,n-1) * 當m = 1,n = 1時,此時就是起始位置,直接返回1; * 當m = 1 時,n為任意值時,則F(1,n) = F(1,n - 1) * 當n = 1 時,m為任意值,則F(m,1) = F(m - 1,1) * */
public static int rec_uniquePaths(int m,int n) { if(m == 1 && n == 1) return 1; if(m == 1) return rec_uniquePaths(m, n - 1); if(n == 1) return rec_uniquePaths(m - 1, n); return rec_uniquePaths(m-1, n) + rec_uniquePaths(m, n - 1); }
遞歸法,數據如果大的話,重復計算的數據很多,導致編譯器崩潰,一般不建議使用遞歸
下面我們來說用動態規划來如何解?
/** * * @param m * @param n * @return * * 動態規划:我們可以定義二維數組arr,橫坐標為m,縱坐標為n * 根據題意,我們令arr[0][0] = 1,arr[0][j] = 1,arr[i][0] = 1,其中0<i<m,0<j<n * arr[i][j] = arr[i-1][j] + arr[i][j - 1] * 最后直接返回二維數組最后一個數組 */
//動態規划方法
public static long dp_uniquePaths(int m,int n) { if(m == 1 || n == 1) return 1; long[][] arr = new long[m][n]; arr[0][0] = 1; for(int i = 1;i<m;i++) { for(int j = 1;j<n;j++) { if(i - 1 == 0 ) { arr[i - 1][j] = 1; } if(j - 1 == 0) { arr[i][j - 1] = 1; } arr[i][j] = arr[i - 1][j] + arr[i][j - 1]; } } return arr[m-1][n-1]; }