从零学算法1289

文章介绍了如何解决一个关于nxn整数矩阵的问题,即找到非零偏移下降路径中数字和的最小值。两种解法被提出,一种是每次都选取上一行中除下标相等的最小值,另一种是考虑当前行的最小值和次小值,避免在同一列选取。这两种方法都是通过迭代矩阵并计算路径和来找到最小值。
摘要由CSDN通过智能技术生成

1289.给你一个 n x n 整数矩阵 arr ,请你返回 非零偏移下降路径 数字和的最小值。
非零偏移下降路径 定义为:从 arr 数组中的每一行选择一个数字,且按顺序选出来的数字中,相邻数字不在原数组的同一列。
示例 1:
输入:arr = [[1,2,3],[4,5,6],[7,8,9]]
输出:13
解释:
所有非零偏移下降路径包括:
[1,5,9], [1,5,7], [1,6,7], [1,6,8],
[2,4,8], [2,4,9], [2,6,7], [2,6,8],
[3,4,8], [3,4,9], [3,5,7], [3,5,9]
下降路径中数字和最小的是 [1,5,7] ,所以答案是 13 。

  • 我的原始人解法:分析可以得到,其实就是每次取上一行中除了下标相等的最小值。(还是可以利用 grid 的空间,不过我懒得优化了)
  •   int max = Integer.MAX_VALUE;
      public int minFallingPathSum(int[][] grid) {
          int n = grid.length;
          int[][] ans = new int[n][n];
          int min = max;
          for(int i = 0; i < n; i++){
              for(int j = 0; j < n; j++){
                  if(i == 0){
                      ans[i][j] = grid[i][j];
                  }else{
                      int result = find(ans[i-1], j) + grid[i][j];
                      ans[i][j] = result;
                  }
                  if(i == n-1){
                      min = Math.min(min,ans[i][j]);
                  }
              }
          }
          return min;
      }
      // 取除了 index 为 exclude 的 ans 中的最小值
      int find(int[] ans,int exclude){
          int result = max;
          for(int i = 0;i < ans.length; i++){
              if(i == exclude){
                  continue;
              }
              result = Math.min(result,ans[i]);
          }
          return result;
      }
    
  • 题号:1289
  • 他人解法:如果说没有那个(相邻数字不在原数组的同一列)的条件,那其实直接每一行最小值相加即可,但是现在有了这个,其实只需要得到一个第二小的值,如果最小值的下标和当前位置的下标相等,加上第二小的值即可。
  •   int max = Integer.MAX_VALUE;
      public int minFallingPathSum(int[][] grid) {
          int n = grid.length;
          int min = max;
          // 上一行最小值,次小值,最小值下标
          int firstMin = max;
          int secondMin = max;
          int firstMinIndex = -1;
          for(int i = 0; i < n; i++){
          	// 当前行最小值,次小值,最小值下标
              int firstMin2 = max;
              int secondMin2 = max;
              int firstMinIndex2 = -1;
              int result = 0;
              for(int j = 0; j < n; j++){
                  if(i == 0){
                      result = grid[i][j];
                  }else{
                      result = (j==firstMinIndex? secondMin : firstMin) + grid[i][j];
                  }
                  if(result <= firstMin2){
                      secondMin2 = firstMin2;
                      firstMin2 = result; 
                      firstMinIndex2 = j; 
                  }else if(result <= secondMin2){
                      secondMin2 = result;
                  }
                  if(i == n-1){
                      min = Math.min(min,result);
                  }
              }
              firstMin = firstMin2;
              secondMin = secondMin2;
              firstMinIndex = firstMinIndex2;
          }
          return min;
      }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值