力扣-54. 螺旋矩阵

news/2024/5/20 8:53:01

1.题目

题目地址(54. 螺旋矩阵 - 力扣(LeetCode))

https://leetcode.cn/problems/spiral-matrix/

题目描述

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

 

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

 

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

2.题解

2.1 模拟(图论 + 标记)

思路

使用图论中的方向数组表示方向, 使用标记数组visited标识哪些元素被访问过了,一旦遇到边界或者遇到被访问过的标记就转向即可
标记方式不止一种, 这里也可以直接将遍历过的元素取负值或者赋值为INT_MAX均可

注意判断这里: if(dx < 0 || dx >= row || dy < 0 || dy >= col || visited[dx][dy])
一定要使用熔断机制, 将visited[dx][dy] 放在最后, 否则就会发生数组越界!!!

代码

  • 语言支持:C++

C++ Code:


class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int row = matrix.size(), col = matrix[0].size();vector<vector<int>> visited(row, vector<int>(col, 0));vector<pair<int, int>> dir{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};int cnt = 0, x = 0, y = 0;vector<int> ans;for(int i = 0; i < row * col; i++){ans.push_back(matrix[x][y]);visited[x][y] = 1;int dx = x + dir[cnt].first;int dy = y + dir[cnt].second; if(dx < 0 || dx >= row || dy < 0 || dy >= col || visited[dx][dy]){cnt = (cnt + 1) % 4;dx = x + dir[cnt].first;dy = y + dir[cnt].second; }x = dx;y = dy;}return ans;}
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(m * n)\)
  • 空间复杂度:\(O(m * n)\)

2.2

思路

可以将矩阵看成若干层,首先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元素。
定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。例如,下图矩阵最外层元素都是第 1 层,次外层元素都是第 2 层,剩下的元素都是第 3 层。
每一层的rowBegin, rowEnd, colBegin, colEnd都不同, 每次遍历完一行/一列便更新即可!

代码

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int rowBegin = 0, rowEnd = matrix.size() - 1;    // 行int colBegin = 0, colEnd = matrix[0].size() - 1; // 列vector<int> ans;while (true) {// 从左向右遍历(行)for (int i = colBegin; i <= colEnd; i++)ans.push_back(matrix[rowBegin][i]); // rowBegin 这行已经遍历过了,// 下次不可以再遍历, ++rowBeginif (++rowBegin > rowEnd)break;// 从上向下遍历(列)for (int i = rowBegin; i <= rowEnd; i++)ans.push_back(matrix[i][colEnd]); // colEnd 这列已经遍历过了,// 下次不可以再遍历, --colEndif (--colEnd < colBegin)break;// 从右向左遍历(行)for (int i = colEnd; i >= colBegin; i--)ans.push_back(matrix[rowEnd][i]);if (--rowEnd < rowBegin)break;// 从下向上遍历(列)for (int i = rowEnd; i >= rowBegin; i--)ans.push_back(matrix[i][colBegin]);if(++colBegin > colEnd)break;}return ans;}
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(m * n)\)
  • 空间复杂度:\(O(1)\)

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

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

相关文章

ROS学习--添加依赖相关问题

在自定义话题接口时,步骤如下:新建msg文件夹,并在文件夹下新建xxx.msg 在xxx.msg下编写消息内容并保存 在CmakeLists.txt添加依赖和msg文件目录 在package.xml中添加xxx.msg所需的依赖 编译功能包即可生成python与c++头文件其中在CmakeLists.txt中添加依赖和msg文件目录时需…

卡诺图学习

目录1、最小项2、最小项与卡诺图之间转换卡诺图根据最小项填写卡诺图根据逻辑函数填写卡诺图3、卡诺图化简方法 1、最小项逻辑函数表达式可以使用其最小项相加来表示最小项的定义 一个函数的某个乘积项包含了函数的全部变量,其中每个变量都以原变量或反变量的形式出现,且仅出…

ESP32引脚笔记

ESP32引脚笔记 ESP32建议使用的引脚 可参考下图Euno开发板引脚模拟输入可采用: 32、33、34、35、36、39 数字输出可采用: 上图右侧引脚 SPI : mosi-23, miso-19, clk-18, cs-5 IIC: scl-22, sda-21仅输入引脚 GPIO34~39是GPIs–仅输入的管脚。这些引脚没有内部上拉或下拉电阻。…

pip成功安装gdal的whl文件后,PyCharm仍报错No module named ‘osgeo’

在根据网上的教程,成功pip install 对应的whl文件后,发现PyCharm仍然显示无法调用osgeo。 出现这样的问题,首先关注自己使用的环境,例如我使用的环境是(见下图)但当我打算卸载gdal库后,发现gdal安装的环境地址和我使用的环境地址不同(如下图)啊,原来是安装gdal的环境…

计算机Windows系统优化小知识

本文涉及计算机Windows系统优化小知识,介绍了注册表、虚拟内存、常用优化工具目录目录什么是注册表优化优化工具什么是注册表注册表是保存所有系统设置数据的存储器。注册表保存了 Windows 运行所需的各种参数和设置,以及应用程序相关的所有信息。从 Windows启动开始,到用户…

CUDA和CUDNN版本切换

介绍了cuda和cudnn版本切换的方法,以及设置环境变量的坑0 背景 在用不同框架做深度学习时,难免会遇到需要不同版本的cuda和cudnn版本的情况,如果把原来版本的卸载掉重新安装新版本,则会影响其它框架的使用,最好的方法是在主机上安装多个版本的cuda和cudnn,需要用到哪种就…

计算机DIY之接驳线缆

介绍计算机DIY过程中接驳线缆相关知识,CPU供电、主板主供电、显卡供电、SATA供电、大4pin供电、主板接驳、前面板接驳目录目录 接驳线缆 CPU供电: 主板主供电 显卡供电 SATA供电 大4pin供电 主板接驳 前面板接驳接驳线缆电源插头里还有3条ATX电源专有的线,一条绿色线…

硬盘保存及维护基本常识

介绍硬盘使用寿命、硬盘供电、硬盘保存相关小知识点目录目录 硬盘使用寿命简介 硬盘供电简介 硬盘保存简介硬盘使用寿命简介硬盘在连续使用3-4年后就需要注意了(一般为质保期时间后一点), 5-6年后就需要更换硬盘了. 五年左右的时候留意更换机械硬盘,如果不是特备重要的数据,可…