从零学算法2500

2500.给你一个 m x n 大小的矩阵 grid ,由若干正整数组成。
执行下述操作,直到 grid 变为空矩阵:
从每一行删除值最大的元素。如果存在多个这样的值,删除其中任何一个。
将删除元素中的最大值与答案相加。
注意 每执行一次操作,矩阵中列的数据就会减 1 。
返回执行上述操作后的答案。
示例 1:
输入:grid = [[1,2,4],[3,3,1]]
输出:8
解释:
- 在第一步操作中,从第一行删除 4 ,从第二行删除 3(注意,有两个单元格中的值为 3 ,我们可以删除任一)。在答案上加 4 。
- 在第二步操作中,从第一行删除 2 ,从第二行删除 3 。在答案上加 3 。
- 在第三步操作中,从第一行删除 1 ,从第二行删除 1 。在答案上加 1 。
最终,答案 = 4 + 3 + 1 = 8 。
示例 2:
输入:grid = [[10]]
输出:10
解释:
- 在第一步操作中,从第一行删除 10 。在答案上加 10 。
最终,答案 = 10 。

  • 我的原始人解法,就按照题意循环 n 次,每次都需要找出矩阵中除了已移除的最大值,以及每一行的最大值并移除每一行的最大值。
  •   public int deleteGreatestValue(int[][] grid) {
          int m = grid.length;
          int n = grid[0].length;
          // 将每个数的下标存入 set 作为未移除的数
          Set<Integer> set = new HashSet<>();
          for(int i=0;i<m;i++){
              for(int j=0;j<n;j++){
                  set.add(i*n+j);
              }
          }
          // 最终结果
          int ans = 0;
          for(int k =0;k<n;k++){
          	// 每一轮查询的最大值
              int max = 0;
              for(int i=0;i<m;i++){
              	// 每一行最大值的下标
                  int x=0;
                  // 每一行的最大值
                  int tempMax=0;
                  for(int j=0;j<n;j++){
                      int key = i*n+j;
                      if(set.contains(key)){
                          int val = grid[i][j];
                          if(val > tempMax){
                              x=key;
                              tempMax=val;
                          }
                      }
                  }
                  set.remove(x);
                  max=Math.max(tempMax,max);
              }
              ans+=max;
          }
          return ans;
      }
    
  • 我的优化,想到每一行都要最大值,那么索性将每一行都排序,那么事情就变得简单了,每次把列固定,然后遍历行,找出每一行最大的,然后固定下一列…
  •   public int deleteGreatestValue(int[][] grid) {
          int m = grid.length;
          int n = grid[0].length;
          Set<Integer> set = new HashSet<>();
          for(int i=0;i<m;i++){
              Arrays.sort(grid[i]);
          }
          int ans = 0;
          // 因为寻找过程等于寻找每一行最大值,每一行次大,次次大...然后相加
          // 所以我们从每一行的次次..大开始找到最大相加,结果不变
          // 根据排序后,第一列就是每一行的次次..大,第二列是次..大,最后一列是每一行的最大值
          // 找出每一列最大值相加即可
          for(int i=0;i<n;i++){
              int max = 0;
              for(int j=0;j<m;j++){
                  max=Math.max(grid[j][i],max);
              }
              ans+=max;
          }
          return ans;
      }
    

你可能感兴趣的:(算法学习,#,数组,算法,数据结构)