2020-12-9 不同路徑
阿新 • • 發佈:2020-12-09
題目
解題思路
法一:暴力回溯
看到題目給的示意圖(一個迷宮),首先想到的就是回溯法,使用一個變數count
來記錄路徑的條數,一旦找到一條路徑count
便加一,詳情看程式碼。
class Solution { public: int uniquePaths(int m, int n) { int count = 0; int a = 1, b = 1; // 初始位置為(1,1) findPathCount(count, a, b, m, n); return count; } void findPathCount(int &count, int a, int b, int m, int n){ if (a > m || b > n) // 超出迷宮的範圍便直接退出 return ; if (a == m && b == n){ // 到達終點count加1 count++; return ; } findPathCount(count, a+1, b, m, n); // 往下走&往右走 findPathCount(count, a, b+1, m, n); } };
由於該方法時間複雜度過高,提交後未能通過。
法二:動態規劃
經分析,對於迷宮中除了上邊界與左邊界的任一格\(\left(i,j\right)\),到達該格可能的路徑條數\(dp[i][j]=dp[i-1][j]+dp[i][j-1]\) ,而從起點出發到達上邊界或左邊界的任意一格的路徑數量均能為1,因為機器人只能往下走或往右走。因此可使用動態規劃來解決該問題。詳情看程式碼。
class Solution { public: int uniquePaths(int m, int n) { long long dp[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(mn)\)
空間複雜度:\(O(mn)\)
法三:組合數學
從左上角到右下角的過程中,我們需要向右移動n-1
次,向下移動m-1
次,共移動m+n-2
次。因此路徑的總數,就等於從m+n-2
次移動中選擇m-1
次向下移動的方案數,即組合數:
兩種解法:
- 直接呼叫組合數的API;
- 自己寫程式碼計算;
class Solution { public: int uniquePaths(int m, int n) { long long ans = 1; for (int x = n, y = 1; y < m; ++x, ++y) { ans = ans * x / y; } return ans; } };