矩阵转置法

python的矩阵转置比较简单,也比较好理解

  • 将该螺旋矩阵的第一行加到res中,然后去掉矩阵的第一行
  • 将剩下的矩阵转置,再去掉第一行

就像削苹果一样,每转一下,就去掉第一行

python实现

class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        res = []
        while matrix:
            res += matrix[0]
            matrix = list(zip(*matrix[1:]))[::-1]
        return res

收缩法

首先,螺旋矩阵的运行过程为:一圈一个周期,所以我们只要写出来一圈的逻辑,并找到每圈之间的规律即可

设定四个标识(上下左右),每转一圈,收缩一下。

c++实现

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int> > &matrix) {
        vector<int> res;
        if(matrix.size() == 0) return res;
        // 设定四个位置标识
        int left = 0, right = matrix[0].size()-1;
        int top = 0, below = matrix.size()-1;
        
        while(left < (matrix[0].size()+1)/2 && top < (matrix.size()+1)/2){
            for(int i=left; i<=right; i++){
                res.push_back(matrix[top][i]);  //正行 从左到右
            }
            //结束行永远是正行,如果正行结束的时候已经达到目标数量,直接退出
            if(res.size() == matrix.size() * matrix[0].size()) break;
            for(int i=top+1; i<=below; i++){
                res.push_back(matrix[i][right]);  //正列 从上到下
            }
            //只有一列的情况
            if(res.size() == matrix.size() * matrix[0].size()) break;
            for(int i=right-1; i>=left; i--){
                res.push_back(matrix[below][i]);  //反行 从右到左
            }
            for(int i=below-1; i>=top+1; i--){
                res.push_back(matrix[i][left]);  //反列 从下到上
            }
            top++;    //四个标识收缩
            right--;
            below--;
            left++;
        }
        return res;
    }
};