LeetCode 2946:矩阵循环移位算法解析与优化

发布时间:2026/10/27 7:03:31

LeetCode 2946:矩阵循环移位算法解析与优化 1. 题目背景与核心需求解析LeetCode 2946这道题出现在周赛环境中考察的是对矩阵操作和算法效率的把握。题目要求我们判断两个矩阵是否可以通过循环移位操作相互转换。所谓循环移位指的是将矩阵的某一行或某一列的所有元素整体移动k个位置超出边界的元素从另一端重新进入。这个题目在真实面试中具有典型意义——它考察了以下几个关键能力对矩阵基础操作的熟练程度算法设计时边界条件的处理能力时间复杂度与空间复杂度的权衡意识Python语言中高效处理矩阵的技巧我在第一次接触这道题时最困惑的是如何高效实现行列的循环移位以及如何避免不必要的重复计算。经过多次优化后最终找到了一个时间复杂度O(n^2)的解决方案下面将详细拆解思考过程。2. 矩阵循环移位的本质理解2.1 循环移位的数学表达循环移位操作可以形式化定义为对于矩阵的第i行右移k次相当于将元素从位置j移动到(jk)%n对于第j列下移k次相当于将元素从位置i移动到(ik)%m。这里的n和m分别表示矩阵的列数和行数。举个例子对于一个3x3矩阵1 2 3 4 5 6 7 8 9将其第一行右移1位后变为3 1 2 4 5 6 7 8 92.2 移位操作的等价性判断判断两个矩阵是否可以通过循环移位相互转换关键在于发现移位操作不会改变矩阵的相对结构。具体来说行移位只会改变行内元素的相对位置不会改变列方向上的元素组合列移位只会改变列内元素的相对位置不会改变行方向上的元素组合任何行/列移位都是可逆的操作基于这些观察我们可以得出一个重要结论如果矩阵A能通过循环移位变成矩阵B那么A的每一行元素组成的多重集合必须与B的某一行相同A的每一列元素组成的多重集合必须与B的某一列相同这个结论将是我们算法设计的理论基础。3. 算法设计与实现细节3.1 基础解法暴力枚举最直观的思路是尝试所有可能的行和列移位组合def isSimilar(mat, target): m, n len(mat), len(mat[0]) # 检查行是否匹配 for i in range(m): row mat[i] found False for k in range(n): shifted row[k:] row[:k] if shifted target[i]: found True break if not found: return False # 检查列是否匹配 for j in range(n): col [mat[i][j] for i in range(m)] target_col [target[i][j] for i in range(m)] found False for k in range(m): shifted col[k:] col[:k] if shifted target_col: found True break if not found: return False return True这个解法的时间复杂度是O(m^2 n^2)在m和n较大时比如1000x1000的矩阵会非常低效。3.2 优化解法多重集合比较基于前面的理论观察我们可以先检查行和列的多重集合是否匹配from collections import defaultdict def isSimilar(mat, target): m, n len(mat), len(mat[0]) # 检查行多重集合 mat_rows [tuple(sorted(row)) for row in mat] target_rows [tuple(sorted(row)) for row in target] if sorted(mat_rows) ! sorted(target_rows): return False # 检查列多重集合 mat_cols [] target_cols [] for j in range(n): mat_col [mat[i][j] for i in range(m)] target_col [target[i][j] for i in range(m)] mat_cols.append(tuple(sorted(mat_col))) target_cols.append(tuple(sorted(target_col))) if sorted(mat_cols) ! sorted(target_cols): return False return True这个版本的时间复杂度降到了O(mn log n mn log m)因为需要对每行每列进行排序。3.3 最优解法行模式匹配进一步观察可以发现我们实际上只需要找到一个基准行然后确定其他行相对于这个基准行的移位量即可def isSimilar(mat, target): m, n len(mat), len(mat[0]) # 找到第一行的移位量k first_row mat[0] target_first_row target[0] try: k (target_first_row.index(first_row[0]) - 0) % n except ValueError: return False # 检查所有行是否匹配这个k for i in range(m): shifted_row mat[i][k:] mat[i][:k] if shifted_row ! target[i]: return False # 检查列是否匹配 for j in range(n): col [mat[i][(j - k) % n] for i in range(m)] target_col [target[i][j] for i in range(m)] if col ! target_col: return False return True这个算法的时间复杂度是O(mn)是最优的解法。4. Python实现中的关键技巧4.1 矩阵转置的高效实现在处理列操作时常规的做法是使用列表推导式提取列col [mat[i][j] for i in range(m)]但在Python中使用zip函数转置矩阵更为高效transposed list(zip(*mat)) # 获取第j列 col transposed[j]4.2 循环移位的简洁写法Python的切片操作非常适合实现循环移位# 右移k位 shifted row[k:] row[:k] # 左移k位 shifted row[-k:] row[:-k]4.3 避免不必要的列表创建在比较行和列时直接使用生成器表达式而非创建临时列表可以节省内存# 不推荐的写法 if [mat[i][j] for i in range(m)] [target[i][j] for i in range(m)]: pass # 推荐的写法 if all(mat[i][j] target[i][j] for i in range(m)): pass5. 常见错误与调试技巧5.1 边界条件处理在实现循环移位时容易忽略k大于行长度的case。正确的做法是使用模运算k k % n # 对于行移位 k k % m # 对于列移位5.2 空矩阵处理题目没有明确说明是否会出现空矩阵但好的习惯是处理这种边界情况if not mat or not mat[0]: return not target or not target[0]5.3 元素类型不一致虽然题目通常保证输入是整数矩阵但实际编码时要考虑类型一致性if int(mat[i][j]) ! int(target[i][j]): return False6. 性能优化实战6.1 提前终止检查在发现任何不匹配的行或列时可以立即返回False避免不必要的计算for i in range(m): if tuple(sorted(mat[i])) ! tuple(sorted(target[i])): return False6.2 使用集合加速初步检查在正式比较前可以先检查两个矩阵的元素是否完全相同if {x for row in mat for x in row} ! {x for row in target for x in row}: return False6.3 缓存排序结果对于大型矩阵可以缓存行的排序结果sorted_rows_mat [tuple(sorted(row)) for row in mat] sorted_rows_target [tuple(sorted(row)) for row in target] if sorted(sorted_rows_mat) ! sorted(sorted_rows_target): return False7. 测试用例设计完整的解决方案应该通过以下测试用例相同矩阵mat [[1,2],[3,4]] target [[1,2],[3,4]] assert isSimilar(mat, target)行移位mat [[1,2,3],[4,5,6]] target [[3,1,2],[6,4,5]] assert isSimilar(mat, target)列移位mat [[1,2],[3,4],[5,6]] target [[2,1],[4,3],[6,5]] assert isSimilar(mat, target)不匹配矩阵mat [[1,2],[3,4]] target [[1,3],[2,4]] assert not isSimilar(mat, target)空矩阵mat [] target [] assert isSimilar(mat, target)8. 复杂度分析与对比让我们对比三种解法的性能解法时间复杂度空间复杂度适用场景暴力枚举O(m^2 n^2)O(m n)小矩阵(m,n 100)多重集合O(mn log n mn log m)O(mn)中等矩阵(m,n 1000)行模式匹配O(mn)O(1)任意大小矩阵在实际面试中建议从暴力解法开始逐步优化到最优解并清楚说明每步优化的思路。9. 实际工程中的应用场景虽然这是一个算法题但类似的思想在以下场景中有实际应用图像处理中的循环卷积密码学中的置换操作数据库中的循环冗余检查分布式系统中的数据分片验证理解矩阵的循环移位性质有助于我们在这些领域设计更高效的算法。10. 扩展思考如果题目改为允许任意行和列的独立移位而不需要所有行/列移动相同距离问题会变得更加复杂。这种情况下我们需要对每行找到其在目标矩阵中的对应行确定每行的移位量验证这些移位量是否一致即所有行的移位量相同这实际上将问题转化为了一个图匹配问题可以使用并查集等数据结构来解决。
延伸阅读

更多相关文章

2026/10/27 7:03:31

OpenCV与Python视觉分析实战:工业级应用指南

1. 项目概述:OpenCV与Python的视觉分析黄金组合在工业质检、安防监控、医疗影像等领域,自动化视觉分析正以每年23%的速度增长。而OpenCV作为计算机视觉领域的瑞士军刀,配合Python的简洁高效,构成了当前最主流的视觉处理技术栈。这…

2026/10/27 7:03:31

Python与OpenCV实战:计算机视觉开发指南

1. 项目概述:当Python遇上OpenCV第一次接触OpenCV是在2015年的一个工业质检项目,当时需要实时检测流水线上的产品缺陷。传统人工检测不仅效率低下,而且漏检率高达30%。当我用PythonOpenCV搭建的视觉系统首次实现99.2%的识别准确率时&#xff…

2026/10/27 7:03:31

SpringBoot教学平台实战:排课冲突检测与作业自动归档

简介:这是一套面向计算机专业本科生毕业设计与Java Web开发初学者的SpringBoot线上教学平台实战项目,聚焦教育信息化场景,解决在线课程管理、师生协同学习与教务数字化等核心需求。资源包共816个文件,30.67MB,涵盖130个…

2026/10/27 7:53:35

AI大模型实战:从入门到部署全流程指南

1. 项目概述:AI大模型实战全攻略这个教程的诞生源于我过去三年在AI领域的实战经验。记得第一次接触大模型时,面对海量的专业术语和复杂的代码库,我花了整整两周才跑通第一个demo。现在,我将这些经验浓缩成一套从零开始的完整学习路…

2026/10/27 7:53:35

YOLO26目标检测框架实战:安装、训练与部署全指南

1. 项目概述:YOLO26的进化与核心价值YOLO26作为Ultralytics团队推出的最新目标检测框架,在YOLOv8基础上进行了全面升级。我最近在工业质检项目中实测发现,其mAP指标比前代提升约12%,推理速度却保持在同一水平。这个开源项目最吸引…

2026/10/27 7:53:35

智能CRM系统如何提升企业销售效率与数据管理

1. 为什么企业都在悄悄换掉传统CRM系统?最近两年接触了上百家中小企业的数字化转型案例,发现一个有趣的现象:超过60%的企业在使用传统CRM系统时都面临同样的问题——销售团队抱怨系统难用,管理层觉得数据不准,IT部门被…

2026/10/27 7:53:35

异构DoS攻击下的预设时间控制仿真与MATLAB实现

简介:面向异构DoS攻击下预设时间控制的MATLAB仿真代码包,主要为研究网络化控制、多智能体系统或安全控制方向的学者及研究生,提供从典型工况到混合复杂情景的仿真验证工具。代码包按任务场景划分多个模块,涵盖典型版本、预设时间触…

2026/10/27 7:48:34

工业AI落地 01 AI视觉检测晶圆缺陷识别

如果你在FAB里负责和「缺陷」相关的事,最怕的往往不是设备突然宕机,而是问题发生前毫无征兆——等到月报出来,良率已经阴跌了几个点,单批报废几十片,损失几十万。更难受的是,你翻遍报警记录也找不到“哪一步…

2026/10/26 0:20:20

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/26 1:53:47

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/27 0:59:21

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/27 0:02:28

WorkBuddy_新建任务与工作模式19_“模式选错”的典型代价

“模式选错”的典型代价 摘要 在软件工程中,设计模式、架构模式、并发模式乃至团队协作模式的选择,往往在项目早期就决定了后续的开发效率和维护成本。本文通过多个真实场景,剖析“模式选错”带来的典型代价——包括返工成本、技术债务累积、…

2026/10/27 0:02:28

WorkBuddy_新建任务与工作模式20_新手推荐路径

新手推荐路径 摘要 在 AI 辅助开发工具快速普及的今天,新手面对最多的困惑往往不是"工具够不够强",而是"我该从哪一步开始用"。本文提出一条经过实践验证的三阶段学习路径:先从 Ask(问答式交互)起…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑