给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:

输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。

 

思路:

和前两篇博客的问题类似 每一个位置都是由同一行左边或者上一行相同位置得到 

贴代码吧

public int minPathSum(int[][] grid) {
		if (grid == null || grid.length == 0) {
			return 0;
		}
		int m = grid.length;
		int n = grid[0].length;
		int[][] dp = new int[m][n];
		dp[0][0] = grid[0][0];
		for (int i = 1; i < n; i++) {
			dp[0][i] = grid[0][i] + dp[0][i - 1];
		}
		for (int i = 1; i < m; i++) {
			dp[i][0] = grid[i][0] + dp[i - 1][0];
		}
		for (int i = 1; i < m; i++) {
			for (int j = 1; j < n; j++) {
				dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
			}
		}
		return dp[m - 1][n - 1];
	}

改成一维的动态规划 

和之前博客总结的一样  从前往后的更新  每一个位置更新完了要给同行下一个位置使用

//改成一维  
	public int minPathSum(int[][] grid) {
		if (grid == null || grid.length == 0) {
			return 0;
		}
		int m = grid.length;
		int n = grid[0].length;
		int[] dp = new int[n];
		dp[0]=grid[0][0];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {  				//需要从前往后遍历  每一个位置更新完了要给同行下一个位置
			    if (i==0&&j==0) {  //[0][0]位置
					continue;
				}else if (i==0&&j!=0) {  //第一行其他位置
					dp[j]=dp[j-1]+grid[i][j];
				}else if (j==0) {
					dp[j]=dp[j]+grid[i][j];       //等于上一行相同位置+当前值
				}else {
					dp[j] = Math.min(dp[j], dp[j - 1]) + grid[i][j];
				}
				
			}
		}
		return dp[n - 1];
	}