螺旋方向遍历矩阵

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;
    }
};
    原文作者:vergilzhang
    原文地址: https://www.jianshu.com/p/933f23d55893
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞