1. 题目

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].

2. 思路

循环顺时针遍历当前最外围的一圈。每次时一个矩形的四边,每个边为了避免起、终的重复,都是从起点到终点的前一个。这是有一个特殊的就是,当只剩下单行或者单列的时候,因为边的起点等于终点,导致都不会输出,因此要特殊处理一下。

3. 代码

耗时:3ms

class Solution {
public:
    // 一圈圈的转,每次转最外面的一圈。
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> ret;
        int ki = 0;
        int kj = 0; // 左上顶点的坐标
        const int m = matrix.size();
        if (m == 0) {return ret;}
        const int n = matrix[0].size();  // m*n的矩阵
        while (ki < (m+1)/2 && kj < (n+1)/2) {
            // 最后单列的情况,单点当做长度为1的单列
            if (kj == n-kj-1) {
                for (int i = ki; i < m-ki; i++) {
                    ret.push_back(matrix[i][n-kj-1]);
                }
                return ret;
            }
            // 最后单行的情况
            if (ki == m-ki-1) {
                for (int j = kj; j < n-kj; j++) {
                    ret.push_back(matrix[ki][j]);
                }
                return ret;
            }
            
            // 上行[ki, kj] -> [ki, n-kj-1]
            for (int j = kj; j < n-kj-1; j++) {
                ret.push_back(matrix[ki][j]);
            }
            // 右竖[ki, n-kj-1] -> [m-ki-1, n-kj-1]
            for (int i = ki; i < m-ki-1; i++) {
                ret.push_back(matrix[i][n-kj-1]);
            }
            // 最后是单列的情况
            
            // 下行[m-ki-1, kj] <- [m-ki-1, n-kj-1]
            for (int j = n-kj-1; j > kj; j--) {
                ret.push_back(matrix[m-ki-1][j]);
            }
            // 左竖[ki, kj] <- [m-ki-1, kj]
            for (int i = m-ki-1; i > ki; i--) {
                ret.push_back(matrix[i][kj]);
            }
            ki++;
            kj++;
        }
        return ret;
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书