从零学算法64

64.给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例 1
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

  • 我的原始人解法:与求不同路径数一样,假设 f(i,j) 为到达左边 (i,j) 的最小总和,只需得到 f(m-1,n-1) 即可,如果贴着墙了,还是一样,比如贴着上墙壁的 (0,1) 此时到达 (0,1) 只可能是从 (0,0) 也就是他的左边过来的, 贴着左墙壁同理,否则就可能为从左或上过来的,根据题目要求,我们取最小值即可
  •   public int minPathSum(int[][] grid) {
          int m = grid.length;
          int n = grid[0].length;
          int[][] ans = new int[m][n];
          ans[0][0] = grid[0][0];
          for(int i=0;i<m;i++){
              for(int j=0;j<n;j++){
                  int temp = grid[i][j];
                  if(i>0 && j>0){
                      ans[i][j] = Math.min(ans[i-1][j],ans[i][j-1])+temp;
                  }else if(i>0){
                      ans[i][j] = ans[i-1][j] + temp;
                  }else if(j>0){
                      ans[i][j] = ans[i][j-1] + temp;
                  }
              }
          }
          return ans[m-1][n-1];
      }
    
  • 题号:64
  • 作者解法:思路一致,但代码更简洁
  •   public int minPathSum(int[][] grid) {        
          int m = grid.length, n = grid[0].length;
          int[][] f = new int[m][n];
          for (int i = 0; i < m; i++) {
              for (int j = 0; j < n; j++) {
                  if (i == 0 && j == 0) {
                      f[i][j] = grid[i][j];
                  } else {
                  	// 贴着上墙则取 int 最大值,这样就一定会被 Math.min 淘汰,
                  	// 等于排除了从上墙壁里面钻出来的可能
                      int top  = i - 1 >= 0 ? f[i - 1][j] + grid[i][j] : Integer.MAX_VALUE;
                      // 同理
                      int left = j - 1 >= 0 ? f[i][j - 1] + grid[i][j] : Integer.MAX_VALUE;
                      f[i][j] = Math.min(top, left);
                  }
              }
          }
          return f[m - 1][n - 1];
      }
    
  • 关于使用一维数组来存储二维数组的信息。先说一下二维数组的坐标转成一维数组的下标。说一下我个人的理解,一个 ,m x n 的网格,以 2 x 3 的网格为例,坐标为 (0,0) 的是第 1 个方块,对应到一维数组的下标也就是 0,同理得到 (0,1) => 1, (0,2) => 2,当坐标为 (1,0),由于它上面还有 1 行,而一行有 n 个,也就是 3 个,所以他就是第 1+3 也就是第 4 个方块,对应一维数组下标为 3。此时可以看出二维坐标转一位数组下标就是 i*n + j,因为遍历的 j 一定小于 n (不然数组下标越界了), 所以同理一维数组下标转成二维数组坐标就是 (index/n, index%n)。但是这时怎么用这个一维数组还是个问题,我们尝试用数组来记录这条路径。比如 2 x 2 的网格,最小总和路径为 (0,0) -> (0,1) -> (1,1),按照第几个方块来看其实就是 1->2->4,对应数组下标也就是 0 -> 1 -> 3,那么比如数组 g, g[3(第 4 个方块)] = 1(到达第 4 个方块的前一个方块为第 2 个方块), g[1(第 2 个方块)] = 0(到达第 2 个方块的前一个方块为第 1 个方块),这样就等于存储了坐标移动的路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值