方法一 贪吃蛇法,根据状态判断转移方向
时间复杂度:O(MN),空间复杂度O(MN)。
class Solution {
public:
int n;
int m;
int state=0;
vector<vector<int>> matrix;
vector<vector<int>> path;
vector<int> result;
bool isInArea(int i ,int j){
if(i<0||j<0||i>=n||j>=m) return false;
return true;
}
void dfs(int i ,int j){
if(isInArea(i,j)&&path[i][j]==0){
result.push_back(matrix[i][j]);
path[i][j]=1;
if(state==0){
dfs(i,j+1);
}else if(state==1){
dfs(i+1,j);
}else if(state==2){
dfs(i,j-1);
}else if(state==3){
dfs(i-1,j);
}
}else return;
if(state==0){
state = 1;
dfs(i+1,j);
}else if(state==1){
state = 2;
dfs(i,j-1);
}else if(state==2){
state=3;
dfs(i-1,j);
}else if(state==3){
state= 0;
dfs(i,j+1);
}
}
vector<int> spiralOrder(vector<vector<int>>& matrix_) {
n = matrix_.size();
if(n!=0) m = matrix_[0].size();
vector<vector<int>> path_(n,vector<int>(m,0));
path = path_;
matrix =matrix_;
dfs(0,0);
return result;
}
};
对代码进行精简后:
class Solution {
public:
int director[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
vector<int> result;
bool isInArea(int i ,int j,int n ,int m){
if(i<0||j<0||i>=n||j>=m) return false;
return true;
}
vector<int> spiralOrder(vector<vector<int>>& matrix_) {
if(matrix_.size()==0) return {};
int n = matrix_.size(),m = matrix_[0].size(),size = m*n,i=0,j=0,directorpos=0;
vector<vector<int>> path(n,vector<int>(m,0));
for(int k = 0;k<size;k++){
path[i][j]=1;
result.push_back(matrix_[i][j]);
int nexti = i+director[directorpos][0],nextj = j+director[directorpos][1];
if(!isInArea(nexti,nextj,n,m)||path[nexti][nextj]==1){
directorpos = (directorpos+1)%4;
}
i = i+director[directorpos][0];
j = j+director[directorpos][1];
}
return result;
}
};
方法二:层序访问
时间复杂度O(MN),空间复杂度O(1)
class Solution {
public:
int director[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
vector<int> result;
bool isInArea(int i ,int j,int n ,int m){
if(i<0||j<0||i>=n||j>=m) return false;
return true;
}
vector<int> spiralOrder(vector<vector<int>>& matrix_) {
if(matrix_.size()==0) return {};
int n = matrix_.size(),m = matrix_[0].size(),left=0,right=m-1,top = 0,bottom = n-1;
while(left<=right&&top<=bottom){
for(int j = left;j<=right;j++){
result.push_back(matrix_[top][j]);
}
for(int i = top+1;i<=bottom;i++){
result.push_back(matrix_[i][right]);
}
if(top==bottom||left==right) break;
for(int j = right-1;j>=left;j--){
result.push_back(matrix_[bottom][j]);
}
for(int i = bottom-1;i>top;i--){
result.push_back(matrix_[i][left]);
}
top++;
bottom--;
left++;
right--;
}
return result;
}
};