[Leetcode]120.三角形路徑最小和

AdamWong發表於2019-01-03

---恢復內容開始---

題目的連結

簡單的動態規劃題,使用了二維dp陣列就能很好的表示。

由於有邊界的問題,所以這個dp陣列為 dp[n+1][n+1]。

dp[i][j]意思是終點為(i-1,j-1)點的路徑最小和。

我們需要把這個三角形變成方陣來看,先看看樣例:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

變成方陣之後就變成了

[

[2, INT_MAX,INT_MAX, INT_MAX],

[3,               4,INT_MAX, INT_MAX],

[6,               5,             7, INT_MAX],

[4,               1,             8,              3],

]

有上面方陣很容易得出這個狀態轉移方程為

dp[i][j]=min(dp[i-1][j-1],dp[i-1][j])+triangle[i-1][j-1];

為了避開陣列越界(人i=0或j=0)的問題,我們的dp陣列容量比triange大一:即triangle[i][j]->dp[i+1][j+1]

class Solution {
public:
   int minimumTotal(vector<vector<int>> &triangle)
{
    size_t n = triangle.size();
    int dp[n + 1][n + 1];
    memset(dp, 0x3f, sizeof(dp));
    int ans = INT_MAX;
    dp[1][1] = triangle[0][0];
    for (size_t i = 2; i <= n; i++)
    {
        for (size_t j = 1; j <= triangle[i - 1].size(); j++)
        {
            dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i-1][j-1];
        }
    }
    for (size_t i = 1; i <= n; i++)
    {
        ans = min(ans, dp[n][i]);
    }
    return ans;
}
};

或者根本不用再建立一個新的dp陣列,而是直接在triangle陣列上進行操作。比如

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        if(triangle.size() == 0 || triangle[0].size() == 0) return 0;
        int n = triangle.size();
        for(int i = n - 2; i >= 0; i--)
            for(int j = 0; j < i + 1; j++)
                triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]);
        return triangle[0][0];
    }
};

這一題的升級版問題可以看我的另一篇隨筆: 下降路徑最小和

相關文章