螺旋矩阵

GitHub跳转原题关系图返回列表

维护 top/bottom/left/right 四条边,按右/下/左/上收缩并检查边界,避免单行/单列重复。

OJ: leetcodecn

题目 ID: spiral-matrix

难度:普及+/提高

标签:数组矩阵模拟cpppython

日期: 2026-07-28 22:05

题意

按顺时针螺旋顺序返回 m×n 矩阵中的所有元素。

思路

维护四条边界 top、bottom、left、right,每次按右、下、左、上四个方向遍历,遍历后收缩对应边界。关键是要在左和上方向前检查边界是否仍然有效,防止单行/单列时重复遍历。

代码

cpp
/**
 * Author by Rainboy
 */
// main.cpp:维护四条边界按右/下/左/上收缩。
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>> &matrix) {
        if (matrix.empty())
            return {};
        int t = 0, b = matrix.size() - 1, l = 0, r = matrix[0].size() - 1;
        vector<int> ans;
        while (t <= b && l <= r) {
            for (int j = l; j <= r; j++)
                ans.push_back(matrix[t][j]);
            t++;
            for (int i = t; i <= b; i++)
                ans.push_back(matrix[i][r]);
            r--;
            if (t <= b)
                for (int j = r; j >= l; j--)
                    ans.push_back(matrix[b][j]);
            b--;
            if (l <= r)
                for (int i = b; i >= t; i--)
                    ans.push_back(matrix[i][l]);
            l++;
        }
        return ans;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int m, n;
    cin >> m >> n;
    vector<vector<int>> a(m, vector<int>(n));
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            cin >> a[i][j];
    auto v = Solution().spiralOrder(a);
    for (int x : v)
        cout << x << ' ';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        if not matrix:
            return []
        t, b, l, r = 0, len(matrix) - 1, 0, len(matrix[0]) - 1
        ans = []
        while t <= b and l <= r:
            for j in range(l, r + 1):
                ans.append(matrix[t][j])
            t += 1
            for i in range(t, b + 1):
                ans.append(matrix[i][r])
            r -= 1
            if t <= b:
                for j in range(r, l - 1, -1):
                    ans.append(matrix[b][j])
                b -= 1
            if l <= r:
                for i in range(b, t - 1, -1):
                    ans.append(matrix[i][l])
                l += 1
        return ans


def main() -> None:
    m, n = map(int, input().split())
    a = [list(map(int, input().split())) for _ in range(m)]
    print(*Solution().spiralOrder(a))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(mn),每个元素访问一次。
  • 空间复杂度:O(1),不计答案数组。

总结

螺旋遍历的核心是"边界收缩"的循环不变量。每轮保持 t <= b && l <= r,确保区间非空才执行对应方向的遍历。