题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
样例
输入:
[
[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-n,列号为0-m,每一层从外到里编号为0 - min(n/2, m/2),第k层从(k, k)开始打印,
那么对于第k层来说,上面那行从(k, k) 到 (k, m-k),右边那列从(k, m-k) 到 (n-k, m-k),下面那行从(n-k, m-k) 到 (n-k, k),左边那列从(n-k, k) 到 (k, k),
当k=n-k时,最里面那层就是单独一行;当k=m-k时,最里面那层就是单独一列,这两种情况单独列出即可.
1 class Solution { 2 public: 3 vector<int> printMatrix(vector<vector<int> > matrix) { 4 vector<int> res; 5 int n=matrix.size()-1; 6 if(n<0) return res; 7 int m=matrix[0].size()-1; 8 int k=0;//层号 9 while(k<n-k && k<m-k) { 10 for(int i=k ;i<m-k; i++) res.push_back(matrix[k][i]); 11 for(int i=k; i<n-k; i++) res.push_back(matrix[i][m-k]); 12 for(int i=m-k; i>k; i--) res.push_back(matrix[n-k][i]); 13 for(int i=n-k; i>k; i--) res.push_back(matrix[i][k]); 14 k++; 15 } 16 if(k==n-k)//打印最后一行 17 for(int i=k; i<=m-k; i++) res.push_back(matrix[k][i]); 18 if(k==m-k)//打印最后一列 19 for(int i=k; i<=n-k; i++) res.push_back(matrix[i][k]); 20 return res; 21 } 22 };
②y神的做法:标记访问过的格子,顺时针定义四个方向:上右下左,
从左上角开始遍历,先往右走,走到不能走为止,然后更改到下个方向,再走到不能走为止,依次类推,遍历 n2 个格子后停止。
原链接请 click here.
1 class Solution { 2 public: 3 vector<int> printMatrix(vector<vector<int>>& matrix) { 4 vector<int> res; 5 if (matrix.empty()) return res; 6 int n = matrix.size(), m = matrix[0].size(); 7 vector<vector<bool>> st(n, vector<bool>(m, false)); 8 int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 9 int x = 0, y = 0, d = 1; 10 for (int k = 0; k < n * m; k ++ ) 11 { 12 res.push_back(matrix[x][y]); 13 st[x][y] = true; 14 15 int a = x + dx[d], b = y + dy[d]; 16 if (a < 0 || a >= n || b < 0 || b >= m || st[a][b]) 17 { 18 d = (d + 1) % 4; 19 a = x + dx[d], b = y + dy[d]; 20 } 21 x = a, y = b; 22 } 23 return res; 24 } 25 };