剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 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]
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
注意:本题与主站 54 题相同:https://leetcode-cn.com/problems/spiral-matrix/
题目要求顺时针打印矩阵
[1,2,3]
[4,5,6]
[7,8,9]
我们可以考虑对于越界
或者访问过的
进行拐弯操作
- 拐弯 : 共有
4
个方向,且顺序不能乱 -
- 行不变,列加一
-
- 行加一,列不变
-
- 行不变,列减一
-
- 行减一,列不变
- 我们可以定义方向偏移量数组
dr[]={ 0, 1, 0, -1 }
,和dc[] = { 1, 0, -1, 0 }
对于所有于拐弯点有如下公式
i = (++i) % 4
于是可以写出代码如下
bool vis[128][128];
int dr[] = { 0, 1, 0, -1 },
dc[] = { 1, 0, -1, 0 };
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& mtx) {
int r = 0, c = 0, n = mtx.size();
if(!n) return { };
int m = mtx[0].size();
memset(vis, false, sizeof(vis));
vector<int> ans;
int cnt = n * m, i = 0;
while(cnt --) {
ans.push_back(mtx[r][c]);
// printf("%d %d\n", r, c);
vis[r][c] = true;
int nr = r + dr[i], nc = c + dc[i];
if(nr<0 || nc<0 || nr>=n || nc>=m || vis[nr][nc]) //遇到拐弯点进行拐弯
i = (++i) % 4;
r = r + dr[i], c = c + dc[i]; //走向下一步
}
return ans;
}
};