一.引言

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

例如给定如上 4 x 5 的 0-1 矩阵,由1组成的最大矩形面积为6。

二.寻找最大矩形-数字版

引言中的题目为寻找最大矩形的矩阵版本,在解答矩阵版本之前,先通过数字版本了解解题流程,再看下面的矩阵版本解答就会清晰很多。

1.题目要求

给定n个表示直方图条高的非负整数,其中每个条的宽度为1,求直方图中最大矩形的面积。

2.实现思路

当前数组 [2, 1 ,5, 6, 2, 3] ,可以先采用数形结合的思想看一下:

(1) 针对每一个点,其对应位置的高度为其数组中对应索引的值

(2) 针对每一个点,以该点为起点构造矩形,需要其左右位置的点连续且高度均小于等于自己

(3) 分别向左,向右延伸,寻找高度大于等于自己的点,直到条件不满足退出,此时满足的位置数 + 1[自身] 即为矩形的长 width,对应索引的值即为矩形的高 height,width x height 即为当前点的最大矩形面积

(4) 初始化 max = 0,遍历所有点,更新最大值并返回

Tips:

以位置1为起点构造矩形,左边没有元素,右边元素值小于等于2,结束,此时面积 = 1 x 2 = 2

以位置2为起点构造矩形,左边1个元素满足,右边4个元素满足,结束,此时面积 = 1 x (1+1+4) = 6

......

依次类推,最终得到最大的面积为位置2 与 位置3 重叠的区域,其最大面积为10 :

3.实现代码

实现非常简单,向左向右判断两个 if-else 即可,如果觉得 range 逻辑不太清晰,也可以使用 while-true ,更方便理解

#!/usr/bin/python
# -*- coding: UTF-8 -*-
nums = [2, 1, 5, 6, 2, 3]def findMaxRectangle(nums):row = len(nums)_max = 0for i in range(row):cur_height = nums[i]  # 获取当前 heightcur_width = 1  # 初始化当前 width# 向左寻找for j in range(i - 1, -1, -1):if nums[j] >= cur_height:cur_width += 1else:break# 向右寻找for k in range(i + 1, row, 1):if nums[k] >= cur_height:cur_width += 1else:break# area = width * heightnow_max = cur_width * cur_height_max = max(_max, now_max)print(_max)return _maxmaxArea = findMaxRectangle(nums)
print("最大面积为: %d" % maxArea)

三.寻找最大矩形-矩阵版

1.题目要求

矩阵版本题目这里再重复一下 : 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

2.实现思路

矩阵版的求最大矩形可以拆解为 row 个寻找最大矩形数字版,针对每一行,我们都可以将当前行作为一个数组 nums,每一个点的高度看做其向上数字连续为1的数量,下面图例看一下:

针对第一行:

当前对应的 nums = [1,0,1,0,0] ,此时最大矩形面积为1

......

针对第三行:

当前 nums = [3, 1, 3, 2, 2] 通过上面的 findMaxRectangle 方法对该 nums 遍历寻找最大面积即可

根据上面的解析步骤也就清晰了:

(1) 针对每行,遍历每列,寻找其上面连续为 1 的格点作为该点的 height,完成行 -> nums 的映射

(2) 针对每行生成的 nums ,使用 findMaxRectangle 方法获取其最大面积 max

(3) 将各行的 max 比较,获得最大面积

3.实现代码

nums2 = [[1, 0, 1, 0, 0], [1, 0, 1, 1, 1], [1, 1, 1, 1, 1], [1, 0, 0, 1, 0]]def getHeightList(matrix):_max = 0print("================")for i in nums2:print(i)print("================")# 退出条件if matrix is None or len(matrix) == 0:return 0# 获取矩阵的长,宽row = len(matrix)col = len(matrix[0])cur_height = [0] * col# 累加获取每行对应的 nums 数组for i in range(row):for j in range(col):if (matrix[i][j]) == 1:cur_height[j] += 1else:cur_height[j] = 0# 为每行 nums 数组计算本行的最大矩阵面积cur_max = findMaxRectangle(cur_height)_max = max(cur_max, _max)print("================")return _maxmaxArea = getHeightList(nums2)
print("最大面积为: %d" % maxArea)

可以看到每行对应的面积分别为1,3,6,4,最终取最大6代表当前0-1矩阵可以找出的最大矩形面积

================
[1, 0, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 0, 0, 1, 0]
================
1
3
6
4
================
最大面积为: 6

四.算法分析

最大矩数字版是矩阵版的子集,所以这里只分析矩阵版:

(1) 根据每行数据构造 height nums 数组

时间复杂度: O(n^2)   |  矩阵完整遍历

空间复杂度: O(n)  | 需要一个长度为 row 的数组保存当前 height

(2) 根据数组寻找最大矩形面积 findMaxRectangle

时间复杂度: 遍历行 (n) x 遍历列 (1-n) = O(n) - O(n^2)

遍历列时可能一步不走,也可能遍历全部 col,所以复杂度为 0-n

空间复杂度:

只需要两个临时变量 cur_height ,cur_width 和 _max 变量,基本忽略

(3) 对称性

对于矩阵而言,其形状为 row x col,转置后的矩阵 col x row 在计算最大矩阵面积时二者结果相同,同等条件下调整 row ,col 可以获得更优的速度,下面验证一下:

row = 1000
col = 10
randomMatrix = np.random.randint(0, 2, size=(row, col))
time1 = time.time()
maxArea = getHeightList(randomMatrix)
print("最大面积为: %d" % maxArea)
time2 = time.time()
transpose = np.transpose(randomMatrix)
time3 = time.time()
maxArea = getHeightList(transpose)
print("最大面积为: %d" % maxArea)
time4 = time.time()
print("%d x %d Cost: %s" % (row, col, (time2 - time1)))
print("%d x %d Cost: %s" % (col, row, (time4 - time3)))
1000 x 10 Cost: 0.010404109954833984
10 x 1000 Cost: 0.2546980381011963

可以看到,当 row >> col 的时候,相同矩阵相同算法得到相同答案的速度可以相差几十倍。

Python - 寻找最大矩形 数字版矩阵版相关推荐

  1. 图像处理----入门资料,Matlab r2019最新版,r2008a,《数字图像处理》冈萨雷斯 第三版 《数字图像处理 Matlab 版》

    研究生想研究的方向是图像处理,现在离开学还有四个月,希望能稍微入门吧.同时也希望通过博客的形式记录一下学习的进度,学习的心情.目前学习两周,安装了基本的软件,收集书籍,学习了灰度变换,空间滤波,频率滤 ...

  2. 《基于ArcGIS的Python编程秘笈(第2版)》——第1章 面向ArcGIS的Python语言基础

    本节书摘来自异步社区<基于ArcGIS的Python编程秘笈(第2版)>一书中的第1章,第1.1节,作者: [美]Eric Pimpler(派普勒) 更多章节内容可以访问云栖社区" ...

  3. 《数字图像处理 MATLAB版》学习笔记

    学习教材:<数字图像处理 MATLAB版>(第二版) 冈萨雷斯 学习过程中的图片代码和及我收集的一些关于数字图像处理的其他学习资料,需要的可以评论留下邮箱(需要购买专栏),加油 文章目录 ...

  4. 计算机等级考试二级 Python 语言程序设计考试大纲(2022 版)

    专栏文章索引如下: 考试大纲 第 1 章 程序设计基本方法 第 2 章 Python 语言基本语法元素 第 3 章 基本数据类型 第 4 章 程序的控制结构 第 5 章 函数和代码复用 第 6 章 组 ...

  5. Python倒计时自动发微信(电脑版微信)

    一.前言: Python倒计时自动发微信(电脑版微信登录状态) 二.主要思路及步骤: 1.先启动微信 2.定位到搜索框 3.搜索微信 4.进入聊天窗口 5.粘贴文本内容 6.发送   7.关闭微信窗口 ...

  6. python编程第5版_正版 Python学习手册(原书第5版) python编程从入门到精通 python入门 计算机网络...

    上册 前言1 部分使用入门 章问答环节21 人们为何使用Python21 软件质量22 开发者效率23 Python是一门"脚本语言"吗23 好吧,Python的缺点是什么25 如 ...

  7. python实战一个完整的项目-Python项目开发实战(第2版)高清晰PDF完整版+代码

    会写代码≠能做好项目! 1.建立有序生产环境 2.迅速融入开发团队 3.高效处理项目问题 网罗Python项目开发中的流程,让你的编程事半功倍 Python项目与封装/团队开发环境/问题驱动开发/源码 ...

  8. 《Python知识手册》,V3.0版来了,2021年,走起!

    "种一棵树,最好的时间是十年前,其次是现在." 一.前言 大家好,今天给大家推荐我的一位好朋友,公众号「Python数据之道」号主 Lemon . 从 2017 年开始,Lemon ...

  9. 【资源分享】数字图像处理MATLAB版冈萨雷斯+中文高清版+随书源码链接

    写在这里的初衷,一是备忘,二是希望得到高人指点,三是希望能遇到志同道合的朋友. 目录 1.数字图像处理MATLAB版冈萨雷斯+中文高清版 2.数字图像处理MATLAB版冈萨雷斯随书源码 1.数字图像处 ...

最新文章

  1. 修改Smartfroms默认文本编辑器
  2. 聚合(根)、实体、值对象精炼思考总结
  3. [windows]windows 10 锁屏壁纸保存方法
  4. LDAP第三天 MySQL+LDAP 安装
  5. mysql数据生成词云图_CVPR2018关键字分析生成词云图与查找
  6. linq结果转换object_19.07.26 JS 里的数据类型转换amp;普通类型和对象的区别
  7. 建立一个全数据管理的分析平台,该如何落实?
  8. java代码程序流程思想_控制执行流程——java编程思想第4章
  9. github创建远程仓库
  10. 5点击换gif_小米10最酷截图,只需三步,打造视频带壳+GIF动图
  11. 当vs2005番茄助手试用过期,并报错的解决方法
  12. 计算机前摄像头怎么录视频教程,电脑摄像头录制视频_电脑摄像头录像怎么录...
  13. android开发者模式自动打开位置touch信息
  14. 联想扬天P600台式电脑安装Win10系统方法
  15. Matlab/Simulink 自动代码生成 基于模型设计学习教程(1)---- 环境配置
  16. UnsupportedOperationException:setProperty must be overridden by all subclasses of SOAPMessage解决方法有效
  17. 使用SpringBoot一小时快速搭建一个简单后台管理(后端篇)
  18. 编码(字符串) SDUT
  19. fluent-edem耦合出错,如何继续计算。
  20. 【基于arduino的esp32-cam视频监控简单使用】

热门文章

  1. 判断对象数组中是否存在重复项
  2. C#粘包和分包问题及解决方法
  3. 前段html css部分试卷,CSS美化试卷页面
  4. 判断浏览器(微信、微博、QQ)、操作系统、横竖屏等
  5. 操作系统页面置换算法之先进先出(FIFO)页面置换算法(C语言实现)
  6. 三维格式转换成3dtiles
  7. 云平台编程与开发(六):物联网云平台的架构设计设想(基于X5Cloud云平台)
  8. 微信小程序关闭按钮样式设计
  9. mysql 索引设计_MySQL 索引原理及设计
  10. 化生政组合能选计算机专业吗,选化生政的女生适合什么专业?女生选化生政好吗?...