LeetCode - 64. Minimum Path Sum

64. MinimumPath Sum – 动态规划

Given a m x n grid filled withnon-negative numbers, find a path from top left to bottom right which minimizes thesum of all numbers along its path.

Note: You can only move either down orright at any point in time.

Example:

Input:

[

  [1,3,1],

  [1,5,1],

  [4,2,1]

]

Output: 7

Explanation: Because the path 1→3→1→1→1 minimizes thesum.

思路:

       我一开始的思路就是dfs,直接遍历所有情况,但实际超时了。

void dfs(const vector<vector<int> >& grid, int i, int j, int cur_sum, int& min_sum)
{
    cur_sum += grid[i][j];
    int m = grid.size(), n = grid[0].size();
    if(i == m - 1 && j == n - 1)
    {
        min_sum = min(min_sum, cur_sum);
        return;
    }
        
    if(i < m - 1)
        dfs(grid, i + 1, j, cur_sum, min_sum);
    if(j < n - 1)
        dfs(grid, i, j + 1, cur_sum, min_sum);
}
int minPathSum(vector<vector<int>>& grid)
{
    if(grid.size() == 1)
        return accumulate(grid[0].begin(), grid[0].end(), 0);
       
    int min_sum = 9999999;
    dfs(grid, 0, 0, 0, min_sum);
    return min_sum;
}

正确思路:

    这是一个典型的DP问题,计算到grid[i][j]点的最短距离,state equation 是 S[i][j] = min(S[i - 1][j], S[i][j - 1]) + grid[i][j]。

先计算第一行第一列的所有值,然后从左上到右下一个一个计算,这样很容易得到代码。

int minPathSum(vector<vector<int>>& grid) 
{
    int m = grid.size();
    int n = grid[0].size(); 
    vector<vector<int> > sum(m, vector<int>(n, grid[0][0]));
    for (int i = 1; i < m; i++)
        sum[i][0] = sum[i - 1][0] + grid[i][0];
    for (int j = 1; j < n; j++)
        sum[0][j] = sum[0][j - 1] + grid[0][j];
    for (int i = 1; i < m; i++)
        for (int j = 1; j < n; j++)
            sum[i][j]  = min(sum[i - 1][j], sum[i][j - 1]) + grid[i][j];
    return sum[m - 1][n - 1];
}

优化之后可以得到空间复杂度只有一个vector大小的代码。相当于按列,从最左边到最右边,每列从上至下,判断从[0][0]点,到每一个点的最短路径(不记录路径,只记录路径长度)。其中,cur_path表示的是当前这列,第i行的这个位置的数的path,所以是这个位置上方,以及左侧两个位置的值中较小值加上自身的值。

int minPathSum(vector<vector<int>>& grid)
{
    int m = grid.size();
    int n = grid[0].size();
    vector<int> cur_path(m, 0);
    cur_path[0] = grid[0][0];
    for(int i = 1; i < m; i++)
        cur_path[i] = cur_path[i - 1] + grid[i][0];
    for(int j = 1; j < n; j++)
    {
        cur_path[0] += grid[0][j];
        for(int i = 1; i < m; i++)
        cur_path[i] = min(cur_path[i - 1], cur_path[i]) + grid[i][j];
    }
    return cur_path[m - 1];
}

猜你喜欢

转载自blog.csdn.net/Bob__yuan/article/details/81066026