【面试经典150 | 矩阵】螺旋矩阵

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:模拟
    • 方法二:按层模拟
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【矩阵】【数组】


题目来源

54. 螺旋矩阵


题目解读

从矩阵左上角 (0, 0) 位置开始,按照顺时针旋转方向螺旋遍历依次输出矩阵的所有元素。


解题思路

方法一:模拟

本题一个直观的思路就是按照要求进行模拟。按照 “向右-向下-向左-向上” 的顺序遍历矩阵,读取每个位置的元素到答案数组中。

几个方向上的移动,可以通过坐标加减来实现,设当前位置坐标(行号和列号)为 (x, y),接下来是四个方向移动的坐标变换:

  • 向右:x 不变,y += 1
  • 向下:x += 1y 不变;
  • 向左:x 不变,y -= 1
  • 向上:x -= 1y 不变;

于是,定义一个表示方向的二维数组 dirs[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}},注意第一维表示的方向要与 “向右-向下-向左-向上” 顺序一一对应。

我们还要使用一个数组 visited 来记录当前位置是否遍历过,如果遍历过,我们也要改变遍历的方向,因为要求是螺旋遍历输出所有的元素。

当前的移动方向索引用 dirIdx 表示,初始 dirIdx = 0 表示向右移动。我们从 (0, 0) 位置出发:

  • 将读取到的位置 (row, col) 对应的元素存入答案数组;
  • 更新数组 visited[row][col] = 1
  • 更新下一个将要遍历的位置即 nrow = row + dirs[dirIdx][0]ncol = col + dirs[dirIdx][1]
  • 如果下一个遍历的位置超出了矩阵的边界或者是已经遍历过的位置,那就要改变移动位置方向,即改变 dirIdx
  • 更新下一个位置的真正方向;
  • 如此遍历完所有位置,即可得到最后的答案数组。

实现代码

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int m = matrix.size(), n = matrix[0].size();vector<int> ret(m*n);const int dirs[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};int dirIdx = 0;int visited[m][n];memset(visited, 0, sizeof(visited));int i;int row = 0, col = 0;for(i = 0; i < m*n; ++i) {ret[i] = matrix[row][col];visited[row][col] = 1;int nrow = row + dirs[dirIdx][0];int ncol = col + dirs[dirIdx][1];if(nrow < 0 || nrow >= m || ncol < 0 || ncol >= n || visited[nrow][ncol]) {dirIdx = (dirIdx + 1) % 4;               }row += dirs[dirIdx][0];col += dirs[dirIdx][1];}return ret;}
};

复杂度分析

时间复杂度: O ( m n ) O(mn) O(mn) m m m 为矩阵 matrix 的行数, n n n 为列数。

空间复杂度: O ( 1 ) O(1) O(1)

方法二:按层模拟

可以将矩阵看成若干层,我们一层一层的输出元素。我们定义第 k 层为距离最近边界距离为 k 的所有顶点。

对于每层,我们从左上角开始以顺时针的顺序遍历所有元素。假设当前层的左上角为 (top, left),右下角为 (buttom, right),按照如下顺序进行遍历:

  • 从左到右遍历当前层的上部元素,(top, left)(top, right)
  • 从上到下遍历当前层的右部元素,(top+1, right)(buttom, right)
  • 如果 left < righttop < buttom,则从右到左遍历下部元素,(buttom, right-1)(buttom, left+1);从下到上遍历左部元素,(buttom, left)(top+1, left)

遍历完当前层的所有元素之后,更新层数为下一层,将 ++left++top--right--bottom。继续遍历,直到遍历完所有元素为止。

实现代码

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {if (matrix.size() == 0 || matrix[0].size() == 0) return {};int rows = matrix.size(), columns = matrix[0].size();vector<int> res;int left = 0, right = columns - 1, top = 0, bottom = rows - 1;	// 初始化为第一层while (left <= right && top <= bottom) {for (int column = left; column <= right; ++column) {		// 更新上部res.push_back(matrix[top][column]);}for (int row = top + 1; row <= bottom; ++row) {				// 更新右部res.push_back(matrix[row][right]);}if (left < right && top < bottom) {for (int column = right - 1; column > left; --column) {	// 更新下部res.push_back(matrix[bottom][column]);}for (int row = bottom; row > top; --row) {				// 更新左部res.push_back(matrix[row][left]);}}// 更新到下一层left++;right--;top++;bottom--;}return res;}
};

复杂度分析

时间复杂度: O ( m n ) O(mn) O(mn) m m m 为矩阵 matrix 的行数, n n n 为列数。

空间复杂度: O ( 1 ) O(1) O(1)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C语言实例_调用SQLITE数据库完成数据增删改查

一、SQLite介绍 SQLite是一种轻量级的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是一个开源的、零配置的、服务器端的、自包含的、零管理的、事务性的SQL数据库引擎。它被广泛应用于嵌入式设备、移动设备和桌面应用程序等领域。 SQLite的特点包括&…

【Golang】数组 切片

【Golang】数组 && 切片 1、数组 基本概念 数组是一个由固定长度的特定类型元素组成的序列&#xff0c;一个数组可以由零个或多个元素组成 因为数组的长度是固定的&#xff0c;所以在Go语言中很少直接使用数组 数组初始化 //1、默认数组中的值是类型的默认值 var arr…

华为智能企业上网行为管理安全解决方案(2)

本文承接&#xff1a; https://blog.csdn.net/qq_37633855/article/details/133339254?spm1001.2014.3001.5501 重点讲解华为智能企业上网行为管理安全解决方案的部署流程。 华为智能企业上网行为管理安全解决方案&#xff08;2&#xff09; 课程地址方案部署整体流程组网规划…

ARM-day2

1、1到100累加 .text .global _start_start:MOV r0, #1ADD r1,r0, #1fun:ADD r0,r0,r1ADD r1,r1, #1cmp r1, #0x65moveq PC,LRbl funstop:b stop.end2、思维导图

Spring Boot的自动装配中的@ConditionalOnBean条件装配注解在Spring启动过程中,是如何保证处理顺序靠后的

前言 为什么Spring Boot条件注解那么多&#xff0c;而标题中是ConditionalOnBean呢&#xff1f; 因为&#xff0c;相比之下我们用的比较多的条件装配注解也就是ConditionalOnClass、ConditionalOnBean了&#xff0c;而ConditionalOnClass对顺序并不敏感&#xff08;说白了就是判…

uniapp app 导出excel 表格

直接复制运行 <template><view><button click"tableToExcel">导出一个表来看</button><view>{{ successTip }}</view></view> </template><script>export default {data() {return {successTip: }},metho…

2023年【道路运输企业安全生产管理人员】最新解析及道路运输企业安全生产管理人员考试技巧

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 道路运输企业安全生产管理人员最新解析参考答案及道路运输企业安全生产管理人员考试试题解析是安全生产模拟考试一点通题库老师及道路运输企业安全生产管理人员操作证已考过的学员汇总&#xff0c;相对有效帮助道路运…

JavaSE | 初识Java(五) | 方法的使用

方法就是一个代码片段&#xff0c; 类似于 C 语言中的 " 函数 "。 方法可以是我们代码逻辑更清晰&#xff0c;并且可以服用方法使代码更简洁 方法语法格式 // 方法定义 修饰符 返回值类型 方法名称([参数类型 形参 ...]){ 方法体代码; [return 返回值]; } 实例&…

数据结构:KMP算法的原理图解和代码解析

文章目录 应用场景算法方案算法原理完整代码 本篇总结的是关于串中的KMP算法解析 应用场景 现给定两个串&#xff0c;现在要看较短的一个串是不是较长的串的子串&#xff0c;如果是就输出子串后面的内容&#xff0c;如果不是则输出Not Found 能匹配到&#xff1a; 长串&…

【办公自动化】在Excel中按条件筛选数据并存入新的表(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Java环境配置无效

Java环境配置无效 老是使用1.8版本&#xff0c;象牛皮癣。 查找java来源 where java 打开C:\Windows\System32 删掉java.exe javaaw.exe javaaws.exe 正常

机器人过程自动化(RPA)入门 3. 顺序、流程图和控制流程

到目前为止&#xff0c;我们已经了解了RPA是什么&#xff0c;并且我们已经看到了通过记录任务的活动并运行它来训练UiPath机器人是多么简单。使用记录器的UiPath可以很容易地自动化日常任务。在我们开始自动化复杂的任务之前&#xff0c;让我们学习如何控制从一个到另一个的活动…

python复习

1.python属于解释型语言&#xff0c;解释器逐行解释每一句代码&#xff0c;然后执行 编译型语言需要由编译器生成最终可执行文件再执行 2. #单行注释""" 多行注释 """ 注释快捷键ctrl/ 3.变量是在计算机语言中能储存计算结果或表示某个数据…

探索腾讯企业邮箱替代方案:选择适合你的新邮件服务

腾讯企业邮箱作为一款广受欢迎的企业级电子邮件服务&#xff0c;已经在国内市场占据了相当大的份额。然而&#xff0c;随着全球市场竞争的加剧&#xff0c;腾讯企业邮箱也面临着海外市场的挑战。本文将探讨腾讯企业邮箱出海的劣势&#xff0c;并推荐一些替代品牌&#xff0c;以…

从其它环境转移到Nacos的方法-NacosSync

理解 NacosSync 组件启动 NacosSync 服务通过一个简单的例子&#xff0c;演示如何将注册到 Zookeeper 的 Dubbo 客户端迁移到 Nacos。 介绍 NacosSync是一个支持多种注册中心的同步组件,基于Spring boot开发框架,数据层采用Spring Data JPA,遵循了标准的JPA访问规范,支持多种…

Neural Networks for Fingerprint Recognition

Neural Computation ( IF 3.278 ) 摘要&#xff1a; 在采集指纹图像数据库后&#xff0c;设计了一种用于指纹识别的神经网络算法。当给出一对指纹图像时&#xff0c;算法输出两个图像来自同一手指的概率估计值。在一个实验中&#xff0c;神经网络使用几百对图像进行训练&…

基于SSM的微博系统网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

十四天学会C++之第一天(入门和基本语法)

C的起源和历史 C诞生于20世纪80年代初&#xff0c;它的创造者是计算机科学家Bjarne Stroustrup。当时&#xff0c;Stroustrup在贝尔实验室工作&#xff0c;他希望为C语言添加一些功能&#xff0c;以便更好地支持系统开发。这个愿望促使他创建了C。 C的名字来源于它的基因&…

BIT.8_Linux 多线程

lesson35: 一、 1.OS调度的基本单位&#xff08;0&#xff1a;13&#xff1a;5&#xff09; 2.进程XXXX&#xff08;0&#xff1a;14&#xff1a;15&#xff09; a.进程的内核数据结构包含哪几个部分&#xff1f;&#xff08;n个&#xff09;&#xff08;0&#xff1a;15&a…

24Hibench

1. Hibench 官网 ​ HiBench is a big data benchmark suite that helps evaluate different big data frameworks in terms of speed, throughput and system resource utilizations. It contains a set of Hadoop, Spark and streaming workloads, including Sort, WordCou…