LeetCode 64最小路徑和
阿新 • • 發佈:2018-12-10
題目
給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。
說明:每次只能向下或者向右移動一步。
示例:
輸入: [ [1,3,1], [1,5,1], [4,2,1] ] 輸出: 7 解釋: 因為路徑 1→3→1→1→1 的總和最小。
解釋
此題運用的是動態規劃, 而且和很多題目非常相似,題目要求每次只能向下走一步或者向右走一步。這就規定走到這一個點的路徑只有兩點,就是上面的點和左邊的點。所以每一點的最小cost可以表示為
min(到達上面的點的最小cost, 到達左邊的點的最小cost) + 當前點的 cost
這樣就把問題分成子問題,建立一個二維陣列cost用來儲存到達每一點的最小cost。
遞迴式可以表示為
cost[i][j] = min(cost[i][j - 1] + grid[i][j], cost[i - 1][j] + grid[i][j]);
然後利用一個二層迴圈,把到達每一個點的最小值求出來。返回返回右下角的值即可。
程式碼
int minPathSum(vector<vector<int>>& grid) { vector<vector<int>> cost = grid; int n = grid.size(), m = grid[0].size(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { //處理第一行和第一列的情況,如果不處理的話,陣列會越界 if (i == 0) { //一直向右走 cost[i][j] = cost[i][j - 1] + grid[i][j]; } else if (j == 0) { //一直向下走 cost[i][j] = cost[i - 1][j] + grid[i][j]; } else { //利用遞推式求結果 cost[i][j] = min(cost[i][j - 1] + grid[i][j], cost[i - 1][j] + grid[i][j]); } } } //返回右下角值 return cost[n-1][m-1]; }
總結
- 關鍵的一點就是找出遞推式。看當前最優解能否被前面的值推出
- 儲存原來的資料一般可以用一個二維陣列。但是有一些題目對空間有限制。比如LeetCode 413, 這樣的話就要儘量去優化,看能不能用一維陣列來代替。