剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
普通算法
思路
按右、下、左、上依次通过for循环打印外围。
注意重复输出问题。
实现
vector<int> spiralOrder(vector<vector<int>>& matrix) {if(matrix.size()==0) return {};// if(matrix[0].size()==0) return matrix;int m=matrix.size(),n=matrix[0].size();int Beg=0,iRow=m-1,jCol=n-1;vector<int> ans(m*n,0);int cnt=0;while(cnt<m*n){for(int j=Beg;j<=jCol;j++){ans[cnt++]=matrix[Beg][j];}for(int i=Beg+1;i<=iRow;i++){ans[cnt++]=matrix[i][jCol];}if(cnt==m*n) break; //避免重复输出for(int j=jCol-1;j>=Beg;j--){ans[cnt++]=matrix[iRow][j];}for(int i=iRow-1;i>Beg;i--){ans[cnt++]=matrix[i][Beg];}Beg++;jCol--;iRow--;}return ans;}
复杂度分析
- 时间复杂度:
- 空间复杂度:
,输出答案所用空间
❤❤DFS
思路
根据题目,输出顺序为右下左上,且输出路径只有一条,故可通过DFS来输出该条路径。输出路径需要完成如下两步:
- 判断下一步是否合法(是否在矩阵范围内,以及是否走过)
- 将该步所对应的值输出,并继续走直到走完整个矩阵
实现
```cpp vector> vis; //访问矩阵 vector > dir; //方向 int maxCnt; //总步数 void __DFS(const vector >& matrix,vector & path,int x,int y,int d,int len){ //若已走完整个矩阵,则退出递归
if(len==maxCnt) return;
} bool __check(const vectorif(__check(matrix,x,y)){vis[x][y]=1;path[len]=matrix[x][y];__DFS(matrix,path,x+dir[d][0],y+dir[d][1],d,len+1);}else{//该方向不合法,回退一步换个方向走x-=dir[d][0];y-=dir[d][1];d=(d+1)%4;__DFS(matrix,path,x+dir[d][0],y+dir[d][1],d,len);}
>& matrix,const int x,const int y){ //判断该步(x,y)是否合法 if(x>=0 && y>=0 && x<matrix.size() && y<matrix[0].size() && vis[x][y]==0) return true; else return false; }
vector
复杂度分析
- 时间复杂度:
- 空间复杂度:
题目标题难度划分
| 星级 | 题目难度 |
|---|---|
| ☆ | 简单 |
| ☆☆ | 中等 |
| ☆☆☆ | 困难 |
算法掌握难度程度划分
| 星级 | 掌握难度 |
|---|---|
| 无 | 普通 |
| ❤ | 经典,易掌握 |
| ❤❤ | 经典,略难掌握 |
| ❤❤❤ | 困难 |
