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个元素。