Leetcode 59. 螺旋矩阵 II && 剑指 Offer 29. 顺时针打印矩阵

发布时间 2023-08-21 11:34:31作者: luxiayuai

这两个题非常相似,但是前者较为简单,后者较难。

由于前者访问的矩阵是方阵,因此可以通过迭代去做(因为方阵每次迭代,长和宽缩水的大小是一样的,但是矩阵不可以,因为矩阵最后一次迭代,长和宽的缩水不一定一样)

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0));
        func(res, 0, 0, n, 1);
        return res;
    }

    void func(vector<vector<int>> &res, int i, int j, int n, int v) {
        if(n == 0) return;
        if(n == 1) {
            res[i][j] = v;
        }

        else {
            for(int k = 0; k < n - 1;k ++ ) res[i][j++] = v++;
            for(int k = 0; k < n - 1;k ++ ) res[i++][j] = v++;
            for(int k = 0; k < n - 1; k ++ ) res[i][j--] = v++;
            for(int k = 0; k < n - 1; k ++ ) res[i--][j] = v++;
            func(res, i + 1, j + 1, n - 2, v);   
        }
    }

};

矩阵的操作更为复杂一些,除了要分别定义左右上下,而且每次循环访问一条边后都要判断边界条件。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.size() == 0) return {};
        vector<int> res;
        int l = 0, r = matrix[0].size() - 1, b = matrix.size() - 1, t = 0;

        while(true) {
            for(int i = l; i <= r; i ++ ) res.emplace_back(matrix[t][i]);
            ++ t;
            if(t > b) break;
            for(int i = t; i <= b; i ++ ) res.emplace_back(matrix[i][r]);
            -- r;
            if(l > r) break;
            for(int i = r; i >= l; i -- ) res.emplace_back(matrix[b][i]);
            -- b;
            if(t > b) break;
            for(int i = b;i >= t; i -- ) res.emplace_back(matrix[i][l]);
            ++ l;
            if(l > r) break;
        }
        return res;
    }
};