一、题目
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
二、代码
解法1:递归(时间和空间都比较差)
思路:
- 对于一个矩阵(左上角下标是(x1,y1),右下角下标是(x2,y2)),首先求出外层的矩阵的数组,然后递归去求里面一层的矩阵的数组,然后将两者合并即可
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix,int x1,int y1,int x2,int y2) { //(x1,y1):top left,(x2,y2):lower right
int m=x2-x1+1,n=y2-y1+1;
vector<int> ans(m*n);
if(m==0||n==0) return vector<int>();
if(m==1){
for(int i=0;i<n;++i) ans[i]=matrix[x1][y1+i];
return ans;
}
if(n==1){
for(int i=0;i<m;++i) ans[i]=matrix[x1+i][y1];
return ans;
}
int len1=m*n-(m-2)*(n-2),len2=(m-2)*(n-2);
vector<int> v1(len1),v2=spiralOrder(matrix,x1+1,y1+1,x2-1,y2-1);
for(int i=y1;i<=y2;++i) v1[i-y1]=matrix[x1][i]; //n
for(int i=x1+1;i<=x2;++i) v1[n+i-x1-1]=matrix[i][y2]; //m-1
for(int i=y1;i<=y2-1;++i) v1[n+m-1+i-y1]=matrix[x2][y1+y2-1-i]; //n-1
for(int i=x1+1;i<=x2-1;++i) v1[2*n+m-2+i-(x1+1)]=matrix[x1+x2-i][y1]; //m-2
//merge
for(int i=0;i<len1;++i) ans[i]=v1[i];
for(int i=0;i<len2;++i) ans[i+len1]=v2[i];
return ans;
}
vector<int> spiralOrder(vector<vector<int>>& matrix) {
return spiralOrder(matrix,0,0,matrix.size()-1,matrix[0].size()-1);
}
};
解法2:按层模拟
思路:
- 依次按照从左至右、从上至下、从右至左、从下至上的顺序,不断的展开。
- 用上下界的思想,规定当前层的矩阵的范围。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m=matrix.size(),n=matrix[0].size();
int left=0,right=n-1,top=0,bottom=m-1;
int num=0,size=m*n;
vector<int> ans(size);
while(num<size){
for(int i=left;i<=right;++i)ans[num++]=matrix[top][i];
if(++top>bottom) break;
for(int i=top;i<=bottom;++i)ans[num++]=matrix[i][right];
if(--right<left) break;
for(int i=right;i>=left;--i)ans[num++]=matrix[bottom][i];
bottom--;
for(int i=bottom;i>=top;--i)ans[num++]=matrix[i][left];
left++;
}
return ans;
}
};
要注意的是,更新完top和right以后,要判断一下是否要结束循环,因为可能当前范围的矩阵只有一行或者一列。(不需要去判断bottom和left)