Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、前言
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
题目链接:螺旋矩阵 I。
二、题目要求
样例 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]
复制代码
考察
1.模拟计算
2.建议用时25~35min
复制代码
三、问题分析
这一题主要考察模拟思想,比较经典的一道题目了。
首先我们先来确定方向与边界问题,首先定义为上、下、左、右四个方向,
分别用四个字母 u、d、l、r 代表
其中,u=0(最上面的一行)、d=行数、l=0(最左侧的一列)、r=列数。
看着上面的图我们实际模拟一下每一种情况
-
1->2->3->4 代表着 l->r 的方向,其中行=u,列从l->r逐步+1,到了4之后,向下转向8,那么u下降一行,++u
-
8->12->16 代表着 u->d 的方向,其中列=r,行从u->d逐步+1,到了16之后,向左转向15,那么r向左移动一列,--r
-
15->14->13 代表着 r->l 的方向,其中行=d,列从r->l逐步-1,到了13之后,向上转向9,那么d向上移动一行,--d
-
9->5 代表着 d->u 的方向,其中列=l,行从d->u逐步-1,到了5之后,向右转向,那么l向右移动一列,++l
上面就是一个循环内部的四次操作,对于循环内边界的判断:
- 第一步 ++u>d ,退出循环
- 第二步 --r<l ,退出循环
- 第三步 --d<u ,退出循环
- 第四步 ++l>r ,退出循环
下面代码严格对应上面的步骤,希望大家能够理解。
四、编码实现
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int i,u=0,d=matrix.size()-1,l=0,r=matrix[0].size()-1;//确定边界,初始化数据
vector<int>v;//数组存储
while(1)//循环内四步转换
{
for(i=l;i<=r;i++) v.push_back(matrix[u][i]);//l->r方向
if(++u>d) break;
for(i=u;i<=d;i++) v.push_back(matrix[i][r]);//u->d方向
if(--r<l) break;
for(i=r;i>=l;i--) v.push_back(matrix[d][i]);//r->l方向
if(--d<u) break;
for(i=d;i>=u;i--) v.push_back(matrix[i][l]);//d->u方向
if(++l>r) break;
}
return v;
}
};
复制代码