题目:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例一:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
示例二:
输入: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]
要求:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
思路:
首先我们先来看题目,题目给出了几个提示:从外到里,顺时针。
根据这两个提示,我们就可以想到我们可以模拟这种状态,先将第一行,最后一列,最后一行,第一列看做一个整体,先输出它,然后再将这个整体向内缩小,这样就完成了对题目的模拟。具体如何操作看下面代码。
代码:
class Solution {
public:
vector spiralOrder(vector>& matrix) {
vector ans;
if(matrix.size() == 0 || matrix[0].size() == 0) return ans;
int left = 0;
int right = matrix[0].size() - 1;
int top = 0;
int bottom = matrix.size() - 1;
while(left <= right && top <= bottom){
for(int column = left; column <= right; column ++){//第一行
ans.push_back(matrix[top][column]);
}
for(int row = top + 1; row <= bottom; row ++){//倒数第一列
ans.push_back(matrix[row][right]);
}
if(left < right && top < bottom){
for(int column = right - 1; column > left; column--){//倒数第一行
ans.push_back(matrix[bottom][column]);
}
for(int row = bottom; row > top; row --){//第一列
ans.push_back(matrix[row][left]);
}
}
left++;
right--;
top++;
bottom--;
}
return ans;
}
};
vector
ans; if(matrix.size() == 0 || matrix[0].size() == 0) return ans;
首先ans数组为我们按照题目创建的结果数组,下面的if判断就是为了当给定的数组为空时,直接返回我们刚创建的空数组(题目要求中给出了数组大小可以为0,所以我们要有这步)。
int left = 0;
int right = matrix[0].size() - 1;
int top = 0;
int bottom = matrix.size() - 1;
这些就是我们再下面进行模拟时需要用到的变量,因为我们要涉及到思路中说到的整体的缩小,所以我们需要去使用变量来控制。
left和right就分别是左边界和有边界,top和bottom分别是上边界和下边界。
while(left <= right && top <= bottom){
for(int column = left; column <= right; column ++){//第一行
ans.push_back(matrix[top][column]);
}
for(int row = top + 1; row <= bottom; row ++){//倒数第一列
ans.push_back(matrix[row][right]);
}
if(left < right && top < bottom){
for(int column = right - 1; column > left; column--){//倒数第一行
ans.push_back(matrix[bottom][column]);
}
for(int row = bottom; row > top; row --){//第一列
ans.push_back(matrix[row][left]);
}
}
left++;
right--;
top++;
bottom--;
}
下面这些就是我们对于顺时针输出的模拟,首先输出第一行,也就是第一个for循环,column就是列数,我们要输出的就是行数为top的并且列数在left到right的值。
接下来输出的就是倒数第一列,也就是第二个for循环,row就是行数,我们要输出的是列数为right并且行数在top+1(因为top那一行我们已经输出过最后一个数了,所以此时加一)到bottom的值。
后面的if(left < right && top < bottom)是因为当我们进行到最里层的时候,有可能只剩一行两个元素或者一列两个元素或只剩一个元素时,left = right, top = bottom 会导致我们重复输出一个数,最终导致出错,所以我们在这里进行了一个判断。
第三次输出的就是倒数第一行了,我们要倒着输出(column--)的就是行数为bottom并且列数在right - 1(这里减一的原因和之前top+1的原因一样,都是因为输出过了)到left(不包括left,为了下面输出第一列时服务,这样我们就能直接从bottom开始输出)的值。
第四次输出的就是第一列的值,我们要倒着输出(row--)的就是列数为left并且行数在bottom到top(不包括top,因为这个位置输出第一行时输出过了)的值。
接下来就是我们要进行整体的缩小了,也就是操作各个边界,上边界(top)和左边界(left)++,下边界(bottom)和右边界(right)--;
时间复杂度:O(n*m)
注:n和矩阵的行数,m为矩阵的列数
空间复杂度:O(1)