題目描述
給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和爲最小。
說明:每次只能向下或者向右移動一步。
示例:
輸入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
輸出: 7
解釋: 因爲路徑 1→3→1→1→1 的總和最小。
分析題目
遞歸
對於有些題目,如果我們一下子想不出來解題思路,其實可以稍微對它分析一下,那麼自然就會找到解題的辦法。
根據題中描述,我們知道每次只能向下或者向右移動一步,我們以此爲依據畫出示例中所有可能的路徑👇
很明顯這是一個樹形結構,我們只要算出每個頭結點到葉子結點所經過的路徑和,它們中最小的值就是題目中要求的最小路徑和,因此我們可以嘗試用深度優先搜索
來解決它,第一版程序👇
var minPathSum = function (grid) {
return dfs(0, 0)
function dfs (i, j) {
if (i === grid.length || j === grid[0].length) {
return Number.MAX_SAFE_INTEGER
}
if (i === grid.length - 1 && j === grid[0].length - 1) {
return grid[i][j]
}
return grid[i][j] + Math.min(dfs(i + 1, j), dfs(i, j + 1))
}
}
動態規劃
細心的你可能已經發現,這道題其實可以把它分解爲一個個子問題,而我們只要解決了子問題,那麼只要把子問題合併起來就能給出解。
怎麼說呢?原題目讓我們求到 grid[i][j]
的最小路徑,那麼我們只要找到 grid[i][j]
的上一個或者左一個中和它加起來最小的一個。換成代碼也就是求👉 min = Math.min(grid[i][j] + grid[i - 1][j], gird[i][j] + grid[i][j-1])
具體實現如下👇
var minPathSum = function(grid) {
let x = grid.length - 1, y = grid[0].length - 1
for (let i = 0; i <= x; i++) {
for (let j = 0; j <= y; j++) {
let tmp = grid[i][j]
if (j === 0) {
if (i > 0) {
grid[i][j] = grid[i - 1][j] + tmp
}
} else {
if (i > 0) {
grid[i][j] = Math.min(grid[i - 1][j] + tmp, grid[i][j - 1] + tmp)
} else {
grid[i][j] = grid[i][j - 1] + tmp
}
}
}
}
return grid[x][y]
};
原題地址: https://leetcode-cn.com/probl...
代碼不定時更新,歡迎 star
我的 repo
掃描下方的二維碼或搜索「tony老師的前端補習班」關注我的微信公衆號,那麼就可以第一時間收到我的最新文章。