维护 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,确保区间非空才执行对应方向的遍历。