给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
举个例子:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
定义四个边界变量left = 0
,right = matrix[0].size()
, top = 0
,bottom = matrix.size()
。对于矩阵matrix
,其行的范围是[top, bottom)
,其列的范围是[left, right)
。
算法如下:
- 先根据题目中的规则遍历矩阵
matrix
由left
,right
,top
,bottom
组成的边界上的元素。 - 缩小矩阵的边界(
++left
,--right
,++top
,--bottom
)。如果left >= right
或top >= bottom
结束遍历,否则进入步骤1
。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
//初始化matrix的四个边界left right top bottom
int left = 0, right = matrix[0].size(), top = 0, bottom = matrix.size();
while (left < right && top < bottom) {
//从左到右遍历最上面一行
for (int i = left; i < right; ++i) {
res.push_back(matrix[top][i]);
}
//最上面一行遍历完修改matrix的top边界
++top;
if (top >= bottom) {
break;
}
//从上到下遍历最右边一列
for (int j = top; j < bottom; ++j) {
res.push_back(matrix[j][right - 1]);
}
//最右边一列遍历完修改matrix的right边界
--right;
//如果已经遍历完matrx就结束,防止matrix只有一行或只有一列,走到下面逻辑重复遍历
if (left >= right) {
break;
}
//从右到左遍历最下面一行
for (int k = right - 1; k >= left; --k) {
res.push_back(matrix[bottom - 1][k]);
}
//最下面一行遍历完修改matrix的bottom边界
--bottom;
if (top >= bottom) {
break;
}
//从下到上遍历最左边一列
for (int l = bottom - 1; l >= top; --l) {
res.push_back(matrix[l][left]);
}
++left;
}
return res;
}
};
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
// 初始化matrix的四个边界left right top bottom
int left = 0, right = matrix[0].length, top = 0, bottom = matrix.length;
while (left < right && top < bottom) {
// 从左到右遍历最上面一行
for (int i = left; i < right; ++i) {
res.add(matrix[top][i]);
}
// 最上面一行遍历完修改matrix的top边界
++top;
if (top >= bottom) {
break;
}
// 从上到下遍历最右边一列
for (int j = top; j < bottom; ++j) {
res.add(matrix[j][right - 1]);
}
// 最右边一列遍历完修改matrix的right边界
--right;
// 如果已经遍历完matrix就结束,防止matrix只有一行或只有一列,走到下面逻辑重复遍历
if (left >= right) {
break;
}
// 从右到左遍历最下面一行
for (int k = right - 1; k >= left; --k) {
res.add(matrix[bottom - 1][k]);
}
// 最下面一行遍历完修改matrix的bottom边界
--bottom;
if (top >= bottom) {
break;
}
// 从下到上遍历最左边一列
for (int l = bottom - 1; l >= top; --l) {
res.add(matrix[l][left]);
}
++left;
}
return res;
}
}
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
res = []
# 初始化matrix的四个边界left right top bottom
left, right, top, bottom = 0, len(matrix[0]), 0, len(matrix)
while left < right and top < bottom:
# 从左到右遍历最上面一行
for i in range(left, right):
res.append(matrix[top][i])
# 最上面一行遍历完修改matrix的top边界
top += 1
if top >= bottom:
break
# 从上到下遍历最右边一列
for j in range(top, bottom):
res.append(matrix[j][right - 1])
# 最右边一列遍历完修改matrix的right边界
right -= 1
# 如果已经遍历完matrix就结束,防止matrix只有一行或只有一列,走到下面逻辑重复遍历
if left >= right:
break
# 从右到左遍历最下面一行
for k in range(right - 1, left - 1, -1):
res.append(matrix[bottom - 1][k])
# 最下面一行遍历完修改matrix的bottom边界
bottom -= 1
if top >= bottom:
break
# 从下到上遍历最左边一列
for l in range(bottom - 1, top - 1, -1):
res.append(matrix[l][left])
left += 1
return res
时间复杂度: 需要遍历整个矩阵,所以时间复杂度是O(mn),其中m
是矩阵的行数,n
是矩阵的列数。
空间复杂度: 需要res
来保存结果,所以空间复杂度是O(mn),其中m
是矩阵的行数,n
是矩阵的列数。