【Leet Code】64. Minimum Path Sum---Medium

来源:互联网 发布:王者荣耀手办淘宝 编辑:程序博客网 时间:2024/06/01 07:39

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

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

思路1:

最简单的方法就是利用动态规划,开辟一个新的m x n数组,该数组的每个元素保存的都是从top left到当前元素的最小和。详细步骤:

1)最左侧元素设为当前元素和上面元素的和;

2)最顶端元素设为当前元素和左边元素的和;

3)剩下的元素为该元素位置上min(上面的元素,左边的元素)加上当前元素的和;

4)返回dp[row-1][col-1]即可。

Note:

该方法的空间复杂度为O(m*n),时间复杂度为O(n)。

思路2:

依然使用动态规划,但在代码实现中使用一种技巧来减少占用的空间。

设置状态为flag[i][j]表示到达网格(i,j)的总和的最小的路径的值,则状态转移方程为:

flag[i][j] = min(flag[i-1][j], flag[i][j-1]) + grid[i][j]

在代码实现过程中,用一维数组dp[j]表示外循环第i次迭代内循环第j次迭代对应的sum值。在还没更新状态时,dp[j]对应flag[i-1][j]; dp[j-1]对应flag[i][j-1]。

该方法的空间复杂度为O(n),时间复杂度为O(n)。

思路3:

采用递归策略,从右下角终点开始向前递归,也是利用了问题的最优解包含子问题的最优解这一思想,层层递归,直到起点。

该方法的主要缺点是时间复杂度比较大,对于如下数组,在leetcode中会返回Time Limit Exceeded错误。

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

思路1代码实现:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        vector<vector<int>> dp = grid;                int row = grid.size(), col = grid[0].size();                for(int i = 1; i < row; ++i)            dp[i][0] += dp[i-1][0];                for(int j = 1; j < col; ++j)            dp[0][j] += dp[0][j-1];                for(int i = 1; i < row; ++i)            for(int j = 1; j < col; ++j)                dp[i][j] += min(dp[i-1][j], dp[i][j-1]);                return dp[row-1][col-1];            }};
思路2代码实现:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        int row = grid.size(), col = grid[0].size();        vector<int> dp = grid[0];                for (unsigned int j = 1; j < col; j++)            dp[j] += dp[j-1];                    for (unsigned int i = 1; i < row; i++)         {            dp[0] += grid[i][0];            for (unsigned int j = 1; j < col; j++)                dp[j] = grid[i][j] + min(dp[j-1], dp[j]);        }        return dp[col-1];    }};
思路3代码实现:

class Solution {public:    int minPathSum(vector<vector<int>>& grid) {        int row = grid.size(), col = grid[0].size();                return path_proxy(grid, row-1, col-1);    }    private:    int path_proxy(vector<vector<int>>&grid, int i, int j)    {        if(i == 0 && j == 0) return grid[0][0];        if(i == 0 && j != 0)         {            int result = grid[0][0];            for(int k = 1; k <= j; ++k)                result += grid[0][k];            return result;        }                if(i != 0 && j == 0)         {            int result = grid[0][0];            for(int k = 1; k <= i; ++k)                result += grid[k][0];            return result;        }               return min(path_proxy(grid, i-1, j), path_proxy(grid, i, j-1)) + grid[i][j];    }};

0 0
原创粉丝点击