cpp
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size(); // m 行
int n = matrix[0].size(); // n 列
int left = 0;
int right = n - 1;
int top = 0;
int bottom = m - 1;
vector<int> ans;
while(ans.size() < m * n){
// 1. 上边:从左往右
for(int i = left; i <= right && ans.size() < m * n; i++){
ans.push_back(matrix[top][i]);
}
top++;
// 2. 右边:从上往下
for(int i = top; i <= bottom && ans.size() < m * n; i++){
ans.push_back(matrix[i][right]);
}
right--;
// 3. 下边:从右往左
for(int i = right; i >= left && ans.size() < m * n; i--){
ans.push_back(matrix[bottom][i]);
}
bottom--;
// 4. 左边:从下往上
for(int i = bottom; i >= top && ans.size() < m * n; i--){
ans.push_back(matrix[i][left]);
}
left++;
}
return ans;
}
};
这道题的核心思路就是:用 top、bottom、left、right 四个边界,一圈一圈地向里面缩。
你可以直接记成这个顺序:
上:从左往右
右:从上往下
下:从右往左
左:从下往上
每走完一条边,就把对应边界往里面移动一次:
top++;
right--;
bottom--;
left++;
具体对应关系是:
上边:matrix[top][i] → top++
右边:matrix[i][right] → right--
下边:matrix[bottom][i] → bottom--
左边:matrix[i][left] → left++
例如:
1 2 3
4 5 6
7 8 9
遍历顺序就是:
1 → 2 → 3
↓
4 5 6
↑ ↓
7 ← 8 ← 9
第一圈得到:
1 2 3 6 9 8 7 4
然后四个边界都缩进去,只剩:
5
最终:
1 2 3 6 9 8 7 4 5
你还要固定记住:
int m = matrix.size(); // 行数
int n = matrix[0].size(); // 列数
所以:
m → 行 → top / bottom
n → 列 → left / right
而:
matrix[i][j]
永远是:
matrix[行][列]
i j
最后,代码中的:
ans.size() < m * n
是为了保证总共只加入 m*n 个元素,避免最后只剩一行或一列时重复访问。
你可以把整道题压缩成一句口诀:
上右下左绕一圈,走完一边缩一边,直到取满
m*n个元素。