一、题目要求
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
摘自LeetCode
二、解法1-设定边界 O(M*N)
当进行螺旋时,矩阵是被一层一层“剥开”的:
可以发现矩阵每次旋转360°,矩阵就会少最外面那一层,我们可以把这个表现为上下左右的边界都减少1。代码的具体思路如下:
(1)用4个变量代表矩阵的上下左右边界,并赋初始值;
(2)进入矩阵开始螺旋,具体过程如下(对照代码查看更清晰):
①从左到右:
②从上到下:
③从右到左:
④从下到上:
需要注意的是当前边界的四个角不要重复添加到 ret 中了。
(3)经过(2)之后外面层就添加完了,然后缩小边界,去掉外层。
(4)循环(2)(3)直到全部添加完。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> ret;
int n = matrix.size() * matrix[0].size();
int length_left = 0; // 左边界
int length_right = matrix[0].size() - 1; // 右边界
int width_top = 0; // 上边界
int width_below = matrix.size() - 1; // 下边界
while (true) {
// 从左到右
for (int i = length_left; i <= length_right; i++) {
ret.emplace_back(matrix[width_top][i]);
}
if (ret.size() == n)
break;
// 从上到下
for (int j = width_top + 1; j <= width_below; j++) {
ret.emplace_back(matrix[j][length_right]);
}
if (ret.size() == n)
break;
// 从右到左
for (int m = length_right - 1; m >= length_left; m--) {
ret.emplace_back(matrix[width_below][m]);
}
if (ret.size() == n)
break;
// 从下到上
for (int n = width_below - 1; n > width_top; n--) {
ret.emplace_back(matrix[n][length_left]);
}
if (ret.size() == n)
break;
// 更新左右上下边界
length_left++;
length_right--;
width_top++;
width_below--;
}
return ret;
}
};