[LeetCode]64、最小路徑和

題目描述

給定一個(gè)包含非負(fù)整數(shù)的 m x n 網(wǎng)格,請找出一條從左上角到右下角的路徑,使得路徑上的數(shù)字總和為最小。

說明:每次只能向下或者向右移動(dòng)一步。

示例:

輸入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
輸出: 7
解釋: 因?yàn)槁窂?1→3→1→1→1 的總和最小。

思路解析

找到一條從左上角到右下角的路徑,路徑之和最小。
每個(gè)元素,向右走或者向下走。兩條路,找到一條路徑之和最小的一個(gè)。
cost(i, j)= grid[i][j] + min(cost(i+1, j), cost(i, j+1))
需要求的就是cost(0, 0)
申請動(dòng)態(tài)規(guī)劃數(shù)組dp[m][n],初始化右下角的值grid[m-1][n-1]??紤]bottom和right,能夠直接初始化。dp[m-1][j] = grid[i][j] + dp[i][j+1]
dp[i][n-1] = grid[i][n-1] + dp[i+1][n-1]
除此之外,就是狀態(tài)轉(zhuǎn)移dp[i][j] = grid[i][j] + min(dp[i+1][j], dp[i][j+1])

class Solution:
    def minPathSum(self, grid):
        if not grid:
            return 0
        m = len(grid)
        n = len(grid[0])
        dp = [[0 for _ in range(n)] for _ in range(m)]
       
        for i in range(m-1, -1, -1):
            for j in range(n-1, -1, -1):
                if i == m-1 and j != n-1:
                    dp[i][j] = grid[i][j] + dp[i][j+1]
                elif j == n-1 and i != m-1:
                    dp[i][j] = grid[i][j] + dp[i+1][j]
                elif i != m-1 and j != n-1:
                    dp[i][j] = grid[i][j] + min(dp[i][j+1], dp[i+1][j])
                else:
                    dp[i][j] = grid[i][j]
        return dp[0][0]

AC64

優(yōu)化

每一個(gè)狀態(tài)依賴右側(cè)或者下側(cè)。利用最后一行,沒有向下的,動(dòng)態(tài)轉(zhuǎn)移賦值。在上個(gè)解法中,我們可以用一個(gè)一維數(shù)組來代替二維數(shù)組,dp 數(shù)組的大小和列大小相同。這是因?yàn)閷τ谀硞€(gè)固定狀態(tài),只需要考慮下方和右側(cè)的節(jié)點(diǎn)。首先初始化 dp 數(shù)組最后一個(gè)元素是右下角的元素值,然后我們向左移更新每個(gè) dp(j) 為:

dp(j)=grid(i,j)+min(dp(j),dp(j+1))

我們對于每一行都重復(fù)這個(gè)過程,然后向上一行移動(dòng),計(jì)算完成后 dp(0) 就是最后的結(jié)果。

class Solution:
#     def minPathSum(self, grid):
#         if not grid:
#             return 0
#         m = len(grid)
#         n = len(grid[0])
#         dp = [[0 for _ in range(n)] for _ in range(m)]
       
#         for i in range(m-1, -1, -1):
#             for j in range(n-1, -1, -1):
#                 if i == m-1 and j != n-1:
#                     dp[i][j] = grid[i][j] + dp[i][j+1]
#                 elif j == n-1 and i != m-1:
#                     dp[i][j] = grid[i][j] + dp[i+1][j]
#                 elif i != m-1 and j != n-1:
#                     dp[i][j] = grid[i][j] + min(dp[i][j+1], dp[i+1][j])
#                 else:
#                     dp[i][j] = grid[i][j]
#         return dp[0][0]
    def minPathSum(self, grid):
        if not grid:
            return 0
        m = len(grid)
        n = len(grid[0])
        dp = [0 for _ in range(n)]

        for i in range(m - 1, -1, -1):
            for j in range(n - 1, -1, -1):
                if i == m - 1 and j != n - 1:
                    dp[j] = grid[i][j] + dp[j + 1]
                elif j == n - 1 and i != m - 1:
                    dp[j] = grid[i][j] + dp[j]
                elif i != m - 1 and j != n - 1:
                    dp[j] = grid[i][j] + min(dp[j + 1], dp[j])
                else:
                    dp[j] = grid[i][j]
        return dp[0]

image.png

優(yōu)化

直接在數(shù)組上修改,減少空間復(fù)雜度

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容