首页 > 其他分享 >力扣-54. 螺旋矩阵

力扣-54. 螺旋矩阵

时间:2024-04-27 13:00:11浏览次数:44  
标签:cnt matrix int 54 矩阵 力扣 vector dx dy

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 这行已经遍历过了,
                                          // 下次不可以再遍历, ++rowBegin
            if (++rowBegin > rowEnd)
                break;

            // 从上向下遍历(列)
            for (int i = rowBegin; i <= rowEnd; i++)
                ans.push_back(matrix[i][colEnd]); // colEnd 这列已经遍历过了,
                                                  // 下次不可以再遍历, --colEnd
            if (--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)\)

标签:cnt,matrix,int,54,矩阵,力扣,vector,dx,dy
From: https://www.cnblogs.com/trmbh12/p/18161941

相关文章

  • 力扣-419. 甲板上的战舰
    1.题目题目地址(419.甲板上的战舰-力扣(LeetCode))https://leetcode.cn/problems/battleships-in-a-board/题目描述给你一个大小为mxn的矩阵board表示甲板,其中,每个单元格可以是一艘战舰'X'或者是一个空位'.',返回在甲板board上放置的战舰的数量。战舰只能水平......
  • 力扣-598. 区间加法 II
    1.题目题目地址(598.区间加法II-力扣(LeetCode))https://leetcode.cn/problems/range-addition-ii/题目描述给你一个mx n的矩阵 M和一个操作数组op。矩阵初始化时所有的单元格都为0。ops[i]=[ai,bi]意味着当所有的0<=x<ai和0<=y<bi时,M[x][y]应......
  • 力扣-LCR 126. 斐波那契数
    1.题目题目地址(LCR126.斐波那契数-力扣(LeetCode))https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/题目描述斐波那契数(通常用F(n)表示)形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n......
  • 矩阵快速幂
    1.参考参考:【矩阵快速幂】简单题学「矩阵快速幂」2.定义2.1定义如果直接求取M^n,时间复杂度是O(n),可以定义矩阵乘法,然后用快速幂算法来加速这里M^n的求取,简化时间复杂度为O(logn)主体思路就是不求M^n而是求M^(n/2),然后先不求M^(n/2),先求M^(n/4)具体实现同......
  • TODO-力扣-707. 设计链表
    1.题目题目地址(707.设计链表-力扣(LeetCode))https://leetcode.cn/problems/design-linked-list/题目描述你可以选择使用单链表或者双链表,设计并实现自己的链表。单链表中的节点应该具备两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果......
  • 【刚度矩阵推导】2d frame 单元
    2dframe单元是x-y平面上的单元,每个节点上有2个平移自由度的和一个转动自由度.局部坐标系下,单元位移向量为:\(u=[u_1,u_2,u_3,u_4,u_5,u_6]^{T}\)其局部坐标系下的刚度矩阵可以由2dtruss单元和2dbornoulli-beam单元的刚度矩阵组合而成.使用matlab进行推导:%!b......
  • 【知识点】快速幂与矩阵快速幂
    什么是快速幂,为什么要使用快速幂?Macw:快速幂有好多好处。Penelope:例如?Macw:它比较快。见名知意,快速幂算法可以在非常短的时间内求出一个数的\(n\)次幂。虽然快速幂在初学阶段的应用不算太多,但是快速幂背后的思想是非常值得我们去理解的。举例而言,如果我们要求出\(3^......
  • 矩阵树定理 BEST 定理
    矩阵树定理\(\text{BEST}\)定理证明很复杂,连\(\text{cmd}\)这种无敌神犇都不会,而且对定理本身的可扩展性几乎为\(0\),即每次套用的定理都跟模板一模一样。矩阵树无论任何情况,一定要不能有自环无论任何情况,一定要不能有自环无论任何情况,一定要不能有自环对于无向无权图,......
  • 力扣-118. 杨辉三角
    1.题目介绍题目地址(118.杨辉三角-力扣(LeetCode))https://leetcode.cn/problems/pascals-triangle/题目描述给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例1:输入:numRows=5输出:[[1],......
  • 矩阵树定理 BEST 定理
    矩阵树定理\(\text{BEST}\)定理证明很复杂,连\(\text{cmd}\)这种无敌神犇都不会,而且对定理本身的可扩展性几乎为\(0\),即每次套用的定理都跟模板一模一样。矩阵树无论任何情况,一定要不能有自环无论任何情况,一定要不能有自环无论任何情况,一定要不能有自环对于无向无权图,......