拓扑排序题目:奇怪的打印机 II
文章目录题目标题和出处难度题目描述要求示例数据范围解法思路和算法代码复杂度分析题目标题和出处标题奇怪的打印机 II出处1591. 奇怪的打印机 II难度8 级题目描述要求有一台奇怪的打印机它有如下两个特殊的打印规则每一次操作时打印机会用同一种颜色打印一个矩形的形状每次打印会覆盖矩形对应格子里原本的颜色。一旦矩形根据上面的规则使用了一种颜色那么相同的颜色不能再被使用。给定一个m × n \texttt{m} \times \texttt{n}m×n的矩阵targetGrid \texttt{targetGrid}targetGrid其中targetGrid[row][col] \texttt{targetGrid[row][col]}targetGrid[row][col]是位置(row, col) \texttt{(row, col)}(row, col)的颜色。如果能按照上述规则打印出矩阵targetGrid \texttt{targetGrid}targetGrid返回true \texttt{true}true否则返回false \texttt{false}false。示例示例 1输入targetGrid [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]] \texttt{targetGrid [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]]}targetGrid [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]]输出true \texttt{true}true示例 2输入targetGrid [[1,1,1,1],[1,1,3,3],[1,1,3,4],[5,5,1,4]] \texttt{targetGrid [[1,1,1,1],[1,1,3,3],[1,1,3,4],[5,5,1,4]]}targetGrid [[1,1,1,1],[1,1,3,3],[1,1,3,4],[5,5,1,4]]输出true \texttt{true}true示例 3输入targetGrid [[1,2,1],[2,1,2],[1,2,1]] \texttt{targetGrid [[1,2,1],[2,1,2],[1,2,1]]}targetGrid [[1,2,1],[2,1,2],[1,2,1]]输出false \texttt{false}false解释没有办法得到targetGrid \texttt{targetGrid}targetGrid因为同一种颜色不能在多轮使用。数据范围m targetGrid.length \texttt{m} \texttt{targetGrid.length}mtargetGrid.lengthn targetGrid[i].length \texttt{n} \texttt{targetGrid[i].length}ntargetGrid[i].length1 ≤ m, n ≤ 60 \texttt{1} \le \texttt{m, n} \le \texttt{60}1≤m, n≤601 ≤ targetGrid[row][col] ≤ 60 \texttt{1} \le \texttt{targetGrid[row][col]} \le \texttt{60}1≤targetGrid[row][col]≤60解法思路和算法由于每种颜色只能用于打印一个矩形且同一种颜色只能使用一次因此可以根据每种颜色在矩阵中出现的行下标和列下标的范围确定颜色的边界并根据边界判断每种颜色的打印顺序。如果颜色b bb出现在颜色a aa的边界内则颜色a aa在颜色b bb之前打印。根据每种颜色的打印顺序可以将所有的颜色和顺序看成有向图如果颜色a aa在颜色b bb之前打印则存在一条从a aa指向b bb的有向边。首先遍历矩阵targetGrid \textit{targetGrid}targetGrid得到矩阵中的每种颜色的边界然后遍历矩阵并记录每种颜色的入度和后续颜色得到不同颜色之间的相对打印顺序建立有向图。对于位置( i , j ) (i, j)(i,j)执行如下操作。记curr targetGrid [ i ] [ j ] \textit{curr} \textit{targetGrid}[i][j]currtargetGrid[i][j]即当前位置的颜色是curr \textit{curr}curr。遍历矩阵中出现过的所有颜色对于每种颜色prev \textit{prev}prev如果prev ≠ curr \textit{prev} \ne \textit{curr}prevcurr且当前位置( i , j ) (i, j)(i,j)在颜色prev \textit{prev}prev的边界内则颜色prev \textit{prev}prev在颜色curr \textit{curr}curr之前打印将curr \textit{curr}curr的入度加1 11将curr \textit{curr}curr添加到prev \textit{prev}prev的后续颜色中。建立有向图之后从入度为0 00的颜色开始拓扑排序判断是否可以打印出矩阵targetGrid \textit{targetGrid}targetGrid。可以打印出矩阵targetGrid \textit{targetGrid}targetGrid的条件是所有颜色和相对打印顺序组成的有向图中没有环此时可以按特定顺序打印所有颜色。如果有向图中有环即不同颜色之间的相对打印顺序存在循环依赖则不能打印所有颜色。因此判断是否可以打印出矩阵targetGrid \textit{targetGrid}targetGrid的方法是在拓扑排序的过程中计算遍历过的颜色数量。如果遍历结束之后遍历过的颜色数量等于矩阵中出现过的所有颜色数量则可以打印出矩阵targetGrid \textit{targetGrid}targetGrid返回true \text{true}true否则不能打印出矩阵targetGrid \textit{targetGrid}targetGrid返回false \text{false}false。代码classSolution{publicbooleanisPrintable(int[][]targetGrid){intmaxColor0;intmtargetGrid.length,ntargetGrid[0].length;for(inti0;im;i){for(intj0;jn;j){maxColorMath.max(maxColor,targetGrid[i][j]);}}int[][]boundsnewint[maxColor1][];for(inti0;im;i){for(intj0;jn;j){intcolortargetGrid[i][j];if(bounds[color]null){bounds[color]newint[]{i,i,j,j};}else{int[]boundbounds[color];bound[0]Math.min(bound[0],i);bound[1]Math.max(bound[1],i);bound[2]Math.min(bound[2],j);bound[3]Math.max(bound[3],j);}}}int[]indegreesnewint[maxColor1];ListInteger[]nextArrnewList[maxColor1];for(inti1;imaxColor;i){nextArr[i]newArrayListInteger();}for(inti0;im;i){for(intj0;jn;j){intcurrtargetGrid[i][j];for(intprev1;prevmaxColor;prev){if(prevcurr||bounds[prev]null){continue;}int[]boundbounds[prev];if(ibound[0]ibound[1]jbound[2]jbound[3]){indegrees[curr];nextArr[prev].add(curr);}}}}intcount0;QueueIntegerqueuenewArrayDequeInteger();for(intcolor1;colormaxColor;color){if(indegrees[color]0){queue.offer(color);}}while(!queue.isEmpty()){intcolorqueue.poll();count;ListIntegernextListnextArr[color];for(intnext:nextList){indegrees[next]--;if(indegrees[next]0){queue.offer(next);}}}returncountmaxColor;}}复杂度分析时间复杂度O ( m n c ) O(mnc)O(mnc)其中m mm和n nn分别是矩阵targetGrid \textit{targetGrid}targetGrid的行数和列数c cc是矩阵中的不同颜色数量。计算颜色数量和每种颜色的边界需要O ( m n ) O(mn)O(mn)的时间建立有向图需要O ( m n c ) O(mnc)O(mnc)的时间拓扑排序需要O ( m n c ) O(mnc)O(mnc)的时间因此时间复杂度是O ( m n c ) O(mnc)O(mnc)。空间复杂度O ( m n c ) O(mnc)O(mnc)其中m mm和n nn分别是矩阵targetGrid \textit{targetGrid}targetGrid的行数和列数c cc是矩阵中的不同颜色数量。存储每种颜色的边界需要O ( m n ) O(mn)O(mn)的空间存储图需要O ( m n c ) O(mnc)O(mnc)的空间队列需要O ( c ) O(c)O(c)的空间因此空间复杂度是O ( m n c ) O(mnc)O(mnc)。

相关新闻

GPU驱动及CUDA安装流程介绍

GPU驱动及CUDA安装流程介绍

1、安装前准备工作 确认GPU型号和操作系统版本   准备gpu驱动和CUDA软件包   在nvidia官网进行驱动包下载 2、下载对应的显卡驱动,CUDA驱动等安装包 GPU驱动下载链接 CUDA下载链接   选择合适的操作系统版本进行下载。 Linux系统均选择 Linux 64-bit、CUDA …

2026/9/19 15:11:09 阅读更多 →
Unity射击游戏武器系统开发:模块化设计与Gun Maker插件实战

Unity射击游戏武器系统开发:模块化设计与Gun Maker插件实战

1. 项目概述:为什么我们需要一个武器生成器插件?在Unity里做射击游戏,尤其是FPS(第一人称射击)和TPS(第三人称射击),武器系统绝对是开发周期里最磨人的部分之一。我经历过不止一个项…

2026/9/18 19:34:50 阅读更多 →
基于Codeblock的LVGL模拟器Windows平台环境搭建[带源码]

基于Codeblock的LVGL模拟器Windows平台环境搭建[带源码]

基于Codeblock的LVGL模拟器Windows平台环境搭建 文章目录基于Codeblock的LVGL模拟器Windows平台环境搭建概述一、介绍二、使用CodeBlock版本方法以及需要注意的坑1、下载lvgl模拟器仓库2.下载CodeBlock3.运行工程总结概述 最近在折腾使用ESP32基于Arduino运行lvgl,…

2026/9/16 18:46:38 阅读更多 →

最新新闻

AI编程助手怎么选?从Copilot替代工具到免费方案全面对比

AI编程助手怎么选?从Copilot替代工具到免费方案全面对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 17:56:02 阅读更多 →
SAP寄售结算为何绕不开MRKO?与MIRO的差异及定制开发切入点

SAP寄售结算为何绕不开MRKO?与MIRO的差异及定制开发切入点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 17:56:02 阅读更多 →
NEP 4 解读:NumPy datetime64 与 timedelta64 日期时间类型的设计提案与现代实现

NEP 4 解读:NumPy datetime64 与 timedelta64 日期时间类型的设计提案与现代实现

NEP 4 解读:NumPy datetime64 与 timedelta64 日期时间类型的设计提案与现代实现 【免费下载链接】numpy The fundamental package for scientific computing with Python. 项目地址: https://gitcode.com/gh_mirrors/nu/numpy 导读 NEP 4(全称 …

2026/9/19 17:56:02 阅读更多 →
PHP项目实战:CQRS架构模式如何解决读写性能瓶颈与数据一致性难题

PHP项目实战:CQRS架构模式如何解决读写性能瓶颈与数据一致性难题

前阵子团队接手了一个已经跑了两年的PHP图书管理系统,刚进来的时候代码看着还行,MVC分层规规矩矩的。结果一查线上慢查询日志,问题全出来了:用户查一本书的借阅历史要join六张表,而读者还书的写操作被这些复杂查询拖到…

2026/9/19 17:56:02 阅读更多 →
2C4G机器LNMP环境搭建:Nginx、MySQL、PHP-FPM联调排错

2C4G机器LNMP环境搭建:Nginx、MySQL、PHP-FPM联调排错

简介:这份PDF文档面向需要从零构建Web运行环境的运维人员、后端开发者与计算机专业学生,系统梳理Linux、Nginx、MySQL、PHP四件套的源码编译式搭建流程。资源包内仅含1个PDF文件,体积约3.22MB,以图文排版呈现命令、配置参数与执行…

2026/9/19 17:56:02 阅读更多 →
react-boilerplate 组件测试实战指南:从 Shallow Rendering 到 react-testing-library

react-boilerplate 组件测试实战指南:从 Shallow Rendering 到 react-testing-library

react-boilerplate 组件测试实战指南:从 Shallow Rendering 到 react-testing-library 【免费下载链接】react-boilerplate 🔥 A highly scalable, offline-first foundation with the best developer experience and a focus on performance and best p…

2026/9/19 17:55:02 阅读更多 →

日新闻

BP神经网络时序预测:滑窗长度与多窗口平均策略

BP神经网络时序预测:滑窗长度与多窗口平均策略

简介:面向机器学习、深度学习与数据建模学习者的一份完整研究文献,聚焦BP神经网络在农业产量预测中的应用。文档以1980—2018年全国棉花产量为样本,系统讲解数据归一化处理、激活函数原理、多层神经网络结构搭建及训练流程,展示敏…

2026/9/19 0:00:30 阅读更多 →
Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

上个月调一个Deformable DETR模型,在单卡上要跑将近两天。第二天早上我下意识打开终端翻日志,发现loss从凌晨两点就开始往上爬,一路从0.8涨到1.35,整整六个小时没人发现。那六个小时的训练不仅白跑,还霸占着卡——等于…

2026/9/19 0:00:30 阅读更多 →
OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: htt…

2026/9/19 0:00:30 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/19 3:59:36 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/19 3:53:08 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/19 4:02:43 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →