54. Spiral Matrix

Problem:

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

Example 1:

Input:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]

Example 2:

Input:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]

思路

每次遍历从左上角到右下角的矩形上的所有点,如果为一条线则遍历线上的点,当左上角的点横坐标或者纵坐标超过右下角的点时停止。矩形遍历完后左上角的点向右下方移动,右下角的点向左上方移动。

Solution (C++):

vector<int> spiralOrder(vector<vector<int>>& matrix) {
    vector<int> res;
    if (matrix.empty() || matrix[0].empty())  return {};
    int m = matrix.size(), n = matrix[0].size();
    int a = 0, b = 0, c = m-1, d = n-1;
    while (a <= c && b <= d) {
        rectangle(a, b, c, d, matrix, res);
        ++a; ++b; --c; --d;
    }
    return res;
}
void rectangle(int a, int b, int c, int d, vector<vector<int>>& matrix, vector<int>& res) {
    // 打印左上角为(a, b),右下角为(c, d)的矩形
    if (a > c || b > d)  return;
    else if (a == c) {
        for (int i = b; i <= d; ++i) 
            res.push_back(matrix[a][i]);
    } else if (b == d) {
        for (int i = a; i <= c; ++i) 
            res.push_back(matrix[i][b]);
    } else {
        for (int i = b; i <= d; ++i) 
            res.push_back(matrix[a][i]);
        for (int i = a+1; i <= c; ++i)
            res.push_back(matrix[i][d]);
        for (int i = d-1; i >=b; --i) 
            res.push_back(matrix[c][i]);
        for (int i = c-1; i > a; --i) 
            res.push_back(matrix[i][b]);
    }
}

性能

Runtime: 0 ms  Memory Usage: 6.5 MB

思路

Solution (C++):

vector<int> spiralOrder(vector<vector<int>>& matrix) {
    if (matrix.empty() || matrix[0].empty())  return {};
    vector<vector<int>> direc{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    int m = matrix.size(), n = matrix[0].size();
    vector<int> res;
    vector<int> steps{n, m-1};
    
    int direc_index = 0;
    int x = 0, y = -1;    //初始位置(0, -1)
    
    //direc_index为偶数,则沿上下移动,为奇数,则沿左右移动。以4为周期
    //右→下→左→上
    
    while (steps[direc_index%2]) {
        for (int i = 0; i < steps[direc_index%2]; ++i) {
            x += direc[direc_index][0];
            y += direc[direc_index][1];
            res.push_back(matrix[x][y]);
        }
        steps[direc_index%2]--;
        direc_index = (direc_index + 1) % 4;
    }
    return res;
}

性能

Runtime: 0 ms  Memory Usage: 6.3 MB

思路

Solution (C++):

vector<int> spiralOrder(vector<vector<int>>& matrix) {
    if (matrix.empty() || matrix[0].empty())  return {};
    //vector<vector<int>> direc{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    int m = matrix.size(), n = matrix[0].size();
    vector<int> res;
    vector<int> steps{n, m-1};
    
    int direc_index = 0;
    int x = 0, y = -1;    //初始位置(0, -1)
    
    //direc_index为偶数,则沿上下移动,为奇数,则沿左右移动。以4为周期
    //右→下→左→上
    
    while (steps[direc_index%2]) {
        //int sup = direc_index % 4;
        for (int i = 0; i < steps[direc_index%2]; ++i) {
            switch(direc_index % 4) {
                case 0: y++; break;
                case 1: x++; break;
                case 2: y--; break;
                case 3: x--; break;
            }
            res.push_back(matrix[x][y]);
        }
        steps[direc_index%2]--;
        direc_index = (direc_index + 1) % 4;
    }
    return res;
}

性能

Runtime: 0 ms  Memory Usage: 6.4 MB

相关链接如下:

知乎:littledy

欢迎关注个人微信公众号:小邓杂谈,扫描下方二维码即可

作者:littledy
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/dysjtu1995/p/12296255.html