排序题目:重新排列后的最大子矩阵

题目

标题和出处

标题:重新排列后的最大子矩阵

出处:1727. 重新排列后的最大子矩阵

难度

7 级

题目描述

要求

给定一个大小为 m × n \texttt{m} \times \texttt{n} m×n 的二进制矩阵 matrix \texttt{matrix} matrix,可以将 matrix \texttt{matrix} matrix 中的按任意顺序重新排列。

返回将 matrix \texttt{matrix} matrix 按照最优方案重新排列后,全是 1 \texttt{1} 1 的最大子矩阵面积。

示例

示例 1:

示例 1

输入: matrix   =   [[0,0,1],[1,1,1],[1,0,1]] \texttt{matrix = [[0,0,1],[1,1,1],[1,0,1]]} matrix = [[0,0,1],[1,1,1],[1,0,1]]
输出: 4 \texttt{4} 4
解释:可以按照上图方式重新排列矩阵的每一列。最大的全 1 \texttt{1} 1 子矩阵是上图中加粗的部分,面积为 4 \texttt{4} 4

示例 2:

示例 2

输入: matrix   =   [[1,0,1,0,1]] \texttt{matrix = [[1,0,1,0,1]]} matrix = [[1,0,1,0,1]]
输出: 3 \texttt{3} 3
解释:可以按照上图方式重新排列矩阵的每一列。最大的全 1 \texttt{1} 1 子矩阵是上图中加粗的部分,面积为 3 \texttt{3} 3

示例 3:

输入: matrix   =   [[1,1,0],[1,0,1]] \texttt{matrix = [[1,1,0],[1,0,1]]} matrix = [[1,1,0],[1,0,1]]
输出: 2 \texttt{2} 2
解释:由于只能按整列重新排布,所以没有比面积为 2 \texttt{2} 2 更大的全 1 \texttt{1} 1 子矩形。

数据范围

  • m = matrix.length \texttt{m} = \texttt{matrix.length} m=matrix.length
  • n = matrix[i].length \texttt{n} = \texttt{matrix[i].length} n=matrix[i].length
  • 1 ≤ m × n ≤ 10 5 \texttt{1} \le \texttt{m} \times \texttt{n} \le \texttt{10}^\texttt{5} 1m×n105
  • matrix[i][j] \texttt{matrix[i][j]} matrix[i][j] 0 \texttt{0} 0 1 \texttt{1} 1

解法

思路和算法

由于对矩阵重新排列的规则是按整列重新排列,因此可以对矩阵的每一列做预处理,对于每个元素 1 1 1,计算该元素向上的最大连续 1 1 1 的个数,然后即可单独处理矩阵的每一行。

经过预处理之后,矩阵中的每个元素更新为该元素向上的最大连续 1 1 1 的个数。如果更新后的矩阵中,某一行有 x x x 个元素不小于 y y y x x x y y y 都是正整数),则说明可以将原矩阵重新排列,使得重新排列的矩阵中存在一个以该行为底边的全 1 1 1 子矩阵,该子矩阵的宽度是 x x x,高度是 y y y,面积是 x y xy xy

为了得到最大全 1 1 1 子矩阵的面积,可以将更新后的矩阵的每一行排序,然后对矩阵的每一行按照从大到小的顺序遍历,计算以该行为底边的最大全 1 1 1 子矩阵面积。

对于矩阵的某一行,假设第 k k k 大的元素是 val k \textit{val}_k valk k ≥ 1 k \ge 1 k1),则该行有至少 k k k 个元素不小于 val k \textit{val}_k valk k k k 个最大元素组成的全 1 1 1 子矩阵面积是 val k × k \textit{val}_k \times k valk×k。从大到小遍历该行的每个元素,当元素大于 0 0 0 时使用元素值与元素的排序编号(第 k k k 大的元素的排序编号是 k k k)计算全 1 1 1 子矩阵面积,并维护最大全 1 1 1 子矩阵面积。当遍历到等于 0 0 0 的元素时,该行剩余的元素都是 0 0 0,该行内不可能再遇到全 1 1 1 子矩阵,因此结束遍历该行。

遍历更新后的矩阵的每一行之后,即可得到最大全 1 1 1 子矩阵面积。

代码

class Solution {
    public int largestSubmatrix(int[][] matrix) {
        int maxArea = 0;
        int m = matrix.length, n = matrix[0].length;
        for (int i = 1; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 1) {
                    matrix[i][j] = matrix[i - 1][j] + 1;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            int[] row = matrix[i];
            Arrays.sort(row);
            for (int j = n - 1, k = 1; j >= 0 && row[j] > 0; j--, k++) {
                int area = row[j] * k;
                maxArea = Math.max(maxArea, area);
            }
        }
        return maxArea;
    }
}

复杂度分析

  • 时间复杂度: O ( m n log ⁡ n ) O(mn \log n) O(mnlogn),其中 m m m n n n 分别是矩阵 matrix \textit{matrix} matrix 的行数和列数。遍历并更新矩阵需要 O ( m n ) O(mn) O(mn) 的时间,对更新后的矩阵的每一行排序共需要 O ( m n log ⁡ n ) O(mn \log n) O(mnlogn) 的时间,计算最大面积需要 O ( m n ) O(mn) O(mn) 的时间,时间复杂度是 O ( m n log ⁡ n ) O(mn \log n) O(mnlogn)

  • 空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是矩阵 matrix \textit{matrix} matrix 的列数。对更新后的矩阵的每一行排序需要 O ( log ⁡ n ) O(\log n) O(logn) 的递归调用栈空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值