leetcode 上有一道以螺旋方向遍历矩阵的题目https://leetcode.com/problems/spiral-matrix/#/description
题目描述如下:
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
像这种遍历的题一般都是有规律的,所以要解决这道题我们首先得找出遍历时坐标的规律。
设矩阵大小为 m×n.
我们假设当前坐标为 ( i , j ),起始时就是(0, 0),由于是螺旋前进,所以首先向右直到尽头,然后向下,然后向左,然后向上,最后又是右。所以方向上为【右,下,左,上】循环。
然后我们要考虑,每个方向的步长是多少:
第一圈:
向右前进 n 步。
向下前进 m – 1 步。
向左前进 n – 1 步。
向上前进 m – 2 步。
第二圈:
向右前进 n – 2 步。
向下前进 m – 3 步。
向左前进 n – 3 步。
向上前进 m – 4 步。
… …
第i圈:
向右前进 n – i + 1步。
向下前进 m – i 步。
向左前进 n – i 步。
向上前进 m – i – 1 步。
将这个前进步长序列整理出来就是:
【n, m -1, n – 1, m -2, n -2, m -3, n -3, ……】
对应的前进方向的序列为:
【右, 下, 左, 上,右,下,左,………】
整理为代码如下:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<vector<int>> dirs{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};//RIGHT DOWN LEFT UP
vector<int> res;
int m = matrix.size(); if (m == 0) return res;
int n = matrix[0].size(); if (n == 0) return res;
vector<int> nSteps{n, m-1};
int r = 0;
int c = -1;
int iDir = 0;
while(nSteps[iDir%2]) {
for(int i = 0; i < nSteps[iDir%2];++i) {
r += dirs[iDir%4][0];
c += dirs[iDir%4][1];
cout << "r = " << r << " c = " << c << endl;;
res.push_back(matrix[r][c]);
}
nSteps[iDir%2] --;
iDir ++;
}
return res;
}
};