Leetcode 1727. 具有重排的最大子矩阵

题目要求:

给定一个大小为 m x n 的二进制矩阵,并且允许您以任意顺序重新排列矩阵的列。

对列进行最佳重新排序后,返回矩阵中每个元素都为 1 的最大子矩阵的面积。

输入:矩阵 = [[0,0,1],[1,1,1],[1,0,1]]
输出:4
说明:您可以重新排列列,如上所示。
最大的 1 子矩阵(粗体)的面积为 4。

思路

因为可以改变列的结构,而无法改变矩形的高度,因此可以先计算每个1在矩形中贡献了多少高度。让我们修改矩阵,使每个矩阵[行][列]代表以下值:“如果我们从矩阵[行][列]开始向上移动,有多少个连续的1?”

这次修改的意义何在?现在,我们可以考虑每列在给定行上可以贡献多少高度。看一下底行 [2, 0, 3]。如果我们按降序排序会发生什么?

 

这个排序行 [3, 2, 0] 表示:

  • 在第 0 列,我们看到了三个连续的。
  • 在第 1 列,我们看到两个连续的。
  • 在第 2 列,我们看到了零个连续的。

从视觉上看,这个排序的行代表以下图像: 

现在,希望这个想法很清楚:在每一列 col,我们知道其左侧的每一列的高度都大于或等于当前高度。 这样,我们就可以以列数col+1为基,构成一个当前高度的子矩阵。

我们迭代输入矩阵并跟踪每列出现了多少个连续的矩阵。 为此,对于给定的行 col,我们首先检查矩阵 [行] [列] != 0。如果是,我们将矩阵 [行 - 1] [列] 的值添加到其中。 如果matrix[row][col] = 0,我们什么都不做,这会有效地重置当前列的条纹,因为matrix[row + 1][col]的下一次迭代将引用matrix[row][col],即 0. 如果我们有一个条纹,那么矩阵[行][列]将每行连续增加1。

一旦我们完成了一行的更新,我们就将其降序排序并迭代它,以找到如果我们将当前行视为子矩阵的底部则可以制作的最大子矩阵。 对于排序的 currRow,我们将 currRow[i] 视为高度,将 i + 1 视为基数。 之所以允许我们对每一行进行排序,是因为对每一行进行排序相当于重新排列列,而我们可以自由地这样做。

class Solution {
public:
    int largestSubmatrix(vector<vector<int>>& matrix) {
        int ans = 0;
        for (int i = 0; i < matrix.size(); ++i) {
            for (int j = 0; j < matrix[0].size(); ++j) {
                if (matrix[i][j] != 0 && i > 0) {
                    matrix[i][j] = matrix[i-1][j] + 1;
                }
            }

            vector<int> currRow = matrix[i];
            sort(currRow.begin(), currRow.end(), greater());
            for (int j = 0; j < matrix[0].size(); ++j) {
                ans = max(ans, currRow[j] * (j+1));
            }
        }

        return ans;
    }
};

时间复杂度: O(m⋅n⋅logn)

我们迭代 m 行。 对于每一行,我们更新值的成本为 O(n)。 然后,我们对行进行排序,其成本为 O(n⋅logn)。 最后,我们迭代该行来计算子矩阵面积,其成本为 O(n)。

总的来说,每次 m 迭代的成本为 O(n⋅logn)。

空间复杂度: O(m⋅n)

虽然我们只分配大小为 O(n) 的 currRow,但我们正在修改矩阵。 修改输入通常被认为是一种不好的做法,当你这样做时,你应该将其计入空间复杂度的一部分。

这个题目考察的不是算法或者计算速度,而是把矩形面积转换成列的之前有多少个连续1作为矩形的高的思路(类似dp)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/190592.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【领域驱动设计 学习目标及大纲】从CRUD到架构设计

从2018年至今&#xff0c;已工作了5年有余&#xff0c;回望这5年的工作历程&#xff0c;虽然一直在学习、一直在积累&#xff0c;但其实都在术的层面上停留&#xff0c;也就是具体的技术点。这5年多的时间里其实也不是没有窥道的想法&#xff1a; 一次是2018年刚工作的时候&am…

理解国外大佬用Web做出来跨窗口渲染动画效果

今天刷抖音看见国外一个大佬用Web做出来一个可以跨多浏览器窗口实时互动的渲染动画效果,觉得非常新奇,我就去看了一下源码,作者还写了一个非常好的例子帮助理解,我自己也仿写了作者的例子加深理解 **GitHub预览地址**麻烦帮忙点亮星星谢谢哈哈哈~ 整体思路是监听visibilityStat…

hdlbits系列verilog解答(exams/m2014_q4f)-47

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 实现以下电路&#xff1a; 二、verilog源码 module top_module (input in1,input in2,output out);assign out in1 & (~in2);endmodule三、仿真结果 转载请注明出处&#xff01;

java Swing UI设置统一字体大小

编写一个遍历组件设置字体大小的方法 public static void setUIFont() {Font f new Font("宋体", Font.PLAIN, 18);String names[] {"Label", "CheckBox", "PopupMenu", "MenuItem", "CheckBoxMenuItem", &quo…

函数的防抖与节流

一、函数防抖 &#xff08;一&#xff09;防抖的理解 防抖就是将所有的触发都取消&#xff0c;在规定的时间结束过后才会执行最后一次&#xff0c;也就是说连续快速的触发只会执行最后一次结果。 也可以理解为游戏里的回城按钮&#xff0c;每点一下就会重新刷新回城进度&…

java学习part13Object类和常用方法

1.Object 2.常用方法 2.1clone() clone()就是深拷贝&#xff0c;创建一个同内容新对象。需要实现接口 2.2finalize()已废弃 类似于析构函数&#xff0c;在GC回收之前调用。 System.gc()强制调用gc&#xff0c;然后就能看到finalize()的输出 2.3equals() 对于引用类型可用。…

WIFI模块(esp-01s)获取网络时间与天气信息

目录 一、硬件连接 二、获取网络时间 1、AT指令集 2、具体操作 三、获取天气信息 1、心知天气注册 2、AT指令集 3、具体操作 4、json格式检查 一、硬件连接 WiFi模块的RX连接TTL模块的TX&#xff0c; WiFi模块的TX连接TTL模块的RX&#xff0c;电源与地接对。 插入电脑…

文心一言 VS 讯飞星火 VS chatgpt (143)-- 算法导论12.1 3题

三、用go语言&#xff0c;设计一个执行中序遍历的非递归算法。&#xff08;提示:一种容易的方法是使用栈作为辅助数据结构;另一种较复杂但比较简洁的做法是不使用栈&#xff0c;但要假设能测试两个指针是否相等。&#xff09; 文心一言&#xff0c;代码正常运行&#xff1a; …

基于51单片机的智能垃圾桶硬件设计

**单片机设计介绍&#xff0c; 基于51单片机的智能垃圾桶硬件设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的智能垃圾桶设计旨在通过传感器和控制电路实现智能化的垃圾桶功能。下面是一个简要的硬件设计介绍&…

HCIA-RS基础-距离矢量路由协议

前言&#xff1a; 动态路由协议根据寻径方式可以分为距离矢量路由协议和链路状态路由协议。本文将详细介绍距离矢量路由协议的原理&#xff0c;并阐述其中一个重要概念——路由环路&#xff0c;同时介绍如何避免路由环路的方法。通过学习本文&#xff0c;您将能够深入理解距离矢…

什么是CAS/CAS的应用/CAS的ABA问题

文章目录 CAS1. 什么是CAS2. CAS的应用2.1 实现原子类2.2 实现自旋锁 3. CAS的ABA问题3.1 什么是ABA问题3.2 ABA问题引来的BUG3.3 解决方案 CAS 1. 什么是CAS CAS: 全称Compare and swap, 字面意思:”比较并交换“. 操作: 设V为内存中的值, A为寄存器中的值(旧的预期值), B也…

火柴棒等式

枚举 只要在保证等式正确的基础上判断火柴棒有没有用完就可以 因为数比较小&#xff0c;而且我不知道最大的等式中的数是多少&#xff0c;索性就设置为999了 还好对效率要求不大&#xff08;doge&#xff09; 要不然就得自己慢慢改最大数来试了 代码如下&#xff1a; #in…

Android 单元测试初体验

Android 单元测试初体验 前言一、单元测试是什么&#xff1f;二、简单使用1.依赖2.单元测试代码简单模版及解释 总结 前言 当初在学校学安卓的时候&#xff0c;老师敢教学进度&#xff0c;翻到单元测试这一章节的时候提了两句&#xff0c;没有把单元测试当重点讲&#xff0c;只…

jQuery_09 事件的绑定与使用(on)

jQuery使用on绑定事件 jQuery可以给dom对象添加事件 在程序执行期间动态的处理事件 1. $("选择器").事件名称(事件处理函数) $("选择器") &#xff1a; 选择0或者多个dom对象 给他们添加事件 事件名称&#xff1a;就是js中事件名称去掉on的部分 比如单击…

PTA-7-53 身份证排序

题目&#xff1a; 输入n&#xff0c;然后连续输入n个身份证号。 将每个身份证的年月日抽取出来&#xff0c;按年-月-日格式组装&#xff0c;然后对组装后的年-月-日升序输出。 根据题目要求&#xff0c;代码实现如下&#xff1a; import java.util.Scanner; import java.uti…

linux之间的免密通信原来是这么的简单

linux之间的免密通信原来是这么的简单 何为免密通信&#xff0c;说的大白话就是&#xff0c;我连接你的服务器不需要密码&#xff0c;哈哈&#xff0c;就是所谓的免密通信 今天小编也不讲免密的基本原理了哈&#xff0c;原理的话&#xff0c;百度里面有好多 小编的主要目的呢是…

1.1 半加器

输入1输入2结果进位0000101001101101 半加器: 实现1位的加法 根据结果可知输入1与输入2相加结果 -> 符合 异或门进位 -> 符合 与门最终要么有结果要么有进位,不存在即有结果也有进位 异或门的实现也可以由基本的3个 “与或非” 门实现 与:& , 或:| , 非:! 用这3个…

开通橱窗还能开抖店吗?怎么开通?一篇详解!

我是电商珠珠 开通商品橱窗之后还能开抖店吗&#xff1f;商品橱窗和抖音小店可以同时开吗&#xff1f; 一部分人最初的时候&#xff0c;都觉得直播带货很火&#xff0c;所以就自己去买粉丝或是发视频积攒粉丝&#xff0c;等粉丝够了发现&#xff0c;好像和当初想的不太一样&a…

2017年五一杯数学建模A题公交车排班问题解题全过程文档及程序

2017年五一杯数学建模 A题 公交车排班问题 原题再现 随着徐州市经济的快速发展&#xff0c;公交车系统对于人们的出行扮演着越来越重要的角色。在公交车资源有限的情况下&#xff0c;合理的编排公交车的行车计划成为公交公司亟待解决的问题。以下给出公交车排班问题中的部分名…

Java实现-数据结构 2.时间和空间复杂度

.如何衡量一个算法的好坏&#xff1a;时间复杂度和空间复杂度 算法效率分为时间效率和空间效率&#xff0c;时间效率称为时间复杂度&#xff0c;空间效率称为空间复杂度 时间复杂度 算法的时间复杂度是一个数学函数&#xff0c;它描述了算法的运行时间&#xff0c;一个算法执…