题目描述:

传送门-力扣

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

思路

设置上下左右的边界标志位,然后在while循环里用4个for循环进行打印即可。
有一些细节问题需要进行考虑:

  1. 每个for循环的起始和终止值;
  2. 什么时候跳出while循环;
  3. 什么时候对边界值进行修改。

进行一下模拟:对于题中给出的矩阵,设置4个边界标志:up = 0, down = 3, left = 0, right = 3。
第一个循环用于输出上面的一行,所以边界值是0到3,当输出完最上面一行后,要输出最右面一列,因为最右面一列的最上一个元素已经输出,所以需要在输出完最上面一行和输出最右面一列前进行上边界的修改,后面的同理。

n×n矩阵 和 m×n矩阵的区别

  1. 对于方阵来说,因为边界值每次都移动1,所以宝成up、down、left、right都是对称的,一个while循环后,四个边界组成的还是方阵,始终同时满足up<=down和left<=right,因此按上述思路进行没有问题;
  2. 对于非方阵来说,当列数比行数多的时候,如题目,当最后结束时,up=dowm,但left<right,如不进行条件判断,就会继续进行输出,导致结果错误,这里采用的方法是用一个变量eleNum来表示矩阵元素的个数,只有当eleNum>0的时候进行输出。
class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        if(matrix.size() == 0 || matrix[0].size() == 0)
            return res;

        int row = matrix.size(), col = matrix[0].size(), eleNum = row * col;
        int up = 0, down = row - 1, left = 0, right = col - 1;

        while(eleNum > 0)
        {
            for(int i = left; i <= right && eleNum-- > 0; i++)
                res.push_back(matrix[up][i]);   
            up++;

            for(int i = up; i <= down && eleNum-- > 0; i++)
                res.push_back(matrix[i][right]);
            right--;

            for(int i = right; i >= left && eleNum-- > 0; i--)
                res.push_back(matrix[down][i]);
            down--;

            for(int i = down; i >= up && eleNum-- > 0; i--)
                res.push_back(matrix[i][left]);
            left++;
        }
        return res;
    }
};