删除每行中的最大值

标签: 数组 矩阵 排序 模拟 堆(优先队列)

难度: Easy

给你一个 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 。

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • 1 <= grid[i][j] <= 100

Submission

运行时间: 24 ms

内存: 16.6 MB

class Solution:
    def deleteGreatestValue(self, grid: List[List[int]]) -> int:
        for i in range(len(grid)):
            grid[i].sort(reverse=True)
        a = [0] * len(grid)
        sum = 0
        for i in range(len(grid[0])):
            for j in range(len(grid)):
                a[j] = grid[j][i]
            sum += max(a)
        return (sum)

Explain

题解的主要思路是首先对矩阵的每一行进行逆序排序,使得每行的最大元素都位于行的开始。然后,通过迭代每一列,收集每行的最大未被删除的元素,并累加这些最大值。具体步骤如下:1. 遍历矩阵的每一行,对每一行进行逆序排序。2. 初始化一个等长于行数的数组 a,用于暂存每一列中的最大值。3. 对于每一列,通过列迭代收集每一行对应位置的元素,找出这些元素中的最大值,并累加到结果 sum 中。4. 返回累加的结果 sum。

时间复杂度: O(m * n log n)

空间复杂度: O(m)

class Solution:
    def deleteGreatestValue(self, grid: List[List[int]]) -> int:
        # 对矩阵中每一行进行逆序排序
        for i in range(len(grid)):
            grid[i].sort(reverse=True)
        # 初始化数组a,用于存储每一列的最大值
        a = [0] * len(grid)
        # 初始化累加器
        sum = 0
        # 遍历每一列
        for i in range(len(grid[0])):
            # 收集每一列的最大值
            for j in range(len(grid)):
                a[j] = grid[j][i]
            # 将每一列的最大值累加到sum
            sum += max(a)
        # 返回最终的累加结果
        return sum

Explore

在对每一行进行逆序排序后,每行的元素按照从大到小的顺序排列,因此每行的第一个元素自然是该行的最大值。这种假设在我们已经将每行进行逆序排序后总是成立,因为排序保证了最大值始终出现在行的开始位置。

在题解中,每次操作删除每行的最大值时,如果某一行的元素提前被完全删除,则在后续的列迭代中,此行将不再提供任何元素。在实际实现时,应当检查每行的元素是否还存在,如果某行已无元素,其对应在数组a中的值应当被忽略或设为一个不影响最大值选择的较小值,例如0(假设所有元素均为正数)。这样可以确保不会对总和计算造成影响。

在初始化数组a时,数组的长度设置为行数,是因为在每次迭代过程中,我们关注的是从每一列中收集每一行的对应元素,并找出这些元素中的最大值。由于每次操作都是逐行观察,每行只会对应一个元素进入到数组a中,因此数组a的长度应该与行数相等。如果设置为列数,将无法正确反映每次操作中每行提供的元素,因为行数定义了每次操作的元素个数上限。