blog-web/source/_posts/算法/动态规划(2).md
2018-09-02 00:08:03 +08:00

2.3 KiB

title date tags categories
动态规划(2) 2018-9-1 21:40:02
算法
动态规划
算法

最小路径和

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。

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

这个问题其实和上一篇当中的 最大子序和 可以采用相似的方式来解决 创建一个 m x n 的二维数组 数组中每个位置记录到达该位置的最小路径和 到达该位置的最小路径和 = min(到达左侧位置的最小路径和, 到达上方位置的最小路径和) + 给定数组在当前格的值 同时排除掉第一行和第一列的特殊情况

代码实现

public int minPathSum(int[][] grid) {
  int m = grid.length;
  if(m == 0) {
    return 0;
  }
  int n = grid[0].length;
  if(n == 0) {
    return 0;
  }
  int[][] nums = new int[m][n];
  nums[0][0] = grid[0][0];
  int currentMin = 0;
  for(int i=0 ; i<m ; i++) {
    for(int j=0 ; j<n ; j++) {
      if(i == 0 && j == 0) {
        continue;
      }
      if(i-1 < 0) {
        currentMin = nums[i][j-1];
      } else if (j-1 < 0) {
        currentMin = nums[i-1][j];
      } else {
        currentMin = Math.min(nums[i][j-1], nums[i-1][j]);
      }
      nums[i][j] = grid[i][j] + currentMin;
    }
  }
  return nums[m-1][n-1];
}

时间复杂度是O(mn), 空间复杂度是O(mn) 当然空间复杂度可以继续优化, 完全可以在传入的数组上面直接对数值进行覆盖, 不去开辟额外的空间 让空间复杂度达到O(1)

public int minPathSum(int[][] grid) {
  int m = grid.length;
  if(m == 0) {
    return 0;
  }
  int n = grid[0].length;
  if(n == 0) {
    return 0;
  }
  int currentMin = 0;
  for(int i=0 ; i<m ; i++) {
    for(int j=0 ; j<n ; j++) {
      if(i == 0 && j == 0) {
        continue;
      }
      if(i-1 < 0) {
        currentMin = grid[i][j-1];
      } else if (j-1 < 0) {
        currentMin = grid[i-1][j];
      } else {
        currentMin = Math.min(grid[i][j-1], grid[i-1][j]);
      }
      grid[i][j] = grid[i][j] + currentMin;
    }
  }
  return grid[m-1][n-1];
}