1. 程式人生 > >leetcode-64-最小路徑和

leetcode-64-最小路徑和

題目描述:

給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。

說明:每次只能向下或者向右移動一步。

示例:

輸入:
[
 [1,3,1],
  [1,5,1],
  [4,2,1]
]
輸出: 7
解釋: 因為路徑 1→3→1→1→1 的總和最小。

要完成的函式:

int minPathSum(vector<vector<int>>& grid) 

 

說明:

1、給定一個二維陣列grid,表示一個網格中所有點的代價,要找到一條從網格左上角到右下角的路徑,只能向下走,或者向右走,使得這條路徑上的代價的和最小。

最後返回這個最小的代價和。

 

2、這道題如果使用暴力窮舉法,除了最後一行的元素和最後一列的元素都只有一種選擇外(右下角元素沒有選擇),其餘元素都有兩種選擇。

比如第一行第一列的元素1,可以選擇往右走或者往下走,兩種選擇。

當網格變大之後,窮舉法太耗時了。因此我們採用其他方法。

 

學習過演算法設計的同學一看這道題應該就能想到動態規劃的方法。

我們用動態規劃的方法記錄到達每一個點的最小路徑代價。

左上角的元素的最小路徑代價肯定就是自身。

其餘元素的最小路徑代價,要不就是左邊元素的最小路徑代價+自身代價,要不就是上方元素的最小路徑代價+自身代價,最後兩者之中取一個小的,作為自身這個元素的最小路徑代價。

不斷地迭代下去,最後右下角的元素的最小路徑代價就是我們所求的。

 

程式碼如下:(附詳解)

    int minPathSum(vector<vector<int>>& grid) 
    {
        if(grid.empty())return 0;//如果矩陣是空的,那麼返回0
int hang=grid.size(),lie=grid[0].size(); vector<vector<int>>record(hang,vector<int>(lie,0));//初始化一個矩陣用來記錄每一個點的最小路徑代價

for(int i=0;i<hang;i++) { for(int j=0;j<lie;j++) { if(i==0&j==0)//如果是左上角的元素,代價等於自身 record[i][j]=grid[i][j]; else { if(i==0)//如果是第0行的元素,代價只能從左邊元素“繼承”過來 record[i][j]=record[i][j-1]+grid[i][j]; else if(j==0)//如果是第0列的元素,代價只能從上方元素“繼承”過來 record[i][j]=record[i-1][j]+grid[i][j]; else//如果是中間部分的元素,就取兩者之中小的那一個 record[i][j]=min(record[i][j-1]+grid[i][j],record[i-1][j]+grid[i][j]); } } } return record[hang-1][lie-1]; }

上述程式碼實測8ms,beats 96.95% of cpp submissions。