题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
题目分析
解法一
写一个让矩阵旋转的函数,每次逆时针旋转90度。然后每次输出第一行即可。
// 原矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
// 输出第一行后
5 6 7 8
9 10 11 12
13 14 15 16
// 逆时针旋转90度
8 12 12
7 11 15
6 10 14
5 9 13
// 输出第一行后
7 11 15
6 10 14
5 9 13
但这种操作效率太低,旋转一次的时间复杂度为O(m*n)
。
解法二
从外向内以顺时针顺序输出,可以分解为一层一层的输出。
具体策略是:从外向内每次输出一层,对于每一层,采用上、右、下、左
这样的顺序进行顺时针打印。如果只有一行,则输出上
;如果只有一列,则输出上、右
;
// 原矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
// 输出最外一层后
6 7
10 11
C++
class Solution
{
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
vector<int> ans;
int x1, y1, x2, y2;
for (x1 = y1 = 0, x2 = matrix.size() - 1, y2 = matrix[0].size() - 1; x1 <= x2 && y1 <= y2; x1++, y1++, x2--, y2--)
{
//上
for (int y = y1; y <= y2; y++)
ans.push_back(matrix[x1][y]);
if (x1 == x2) //只有一行
break;
//右
for (int x = x1 + 1; x <= x2; x++)
ans.push_back(matrix[x][y2]);
if (y1 == y2) //只有一列
break;
//下
for (int y = y2 - 1; y >= y1; y--)
ans.push_back(matrix[x2][y]);
//左
for (int x = x2 - 1; x > x1; x--)
ans.push_back(matrix[x][y1]);
}
return ans;
}
};
Java
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int[][] matrix) {
ArrayList<Integer> ans = new ArrayList<>();
int x1, x2, y1, y2;
for (x1 = y1 = 0, x2 = matrix.length - 1, y2 = matrix[0].length - 1; x1 <= x2
&& y1 <= y2; x1++, y1++, x2--, y2--) {
// 上
for (int y = y1; y <= y2; y++)
ans.add(matrix[x1][y]);
if (x1 == x2)// 只有一行
break;
// 右
for (int x = x1 + 1; x <= x2; x++)
ans.add(matrix[x][y2]);
if (y1 == y2)// 只有一列
break;
// 下
for (int y = y2 - 1; y >= y1; y--)
ans.add(matrix[x2][y]);
// 左
for (int x = x2 - 1; x > x1; x--)
ans.add(matrix[x][y1]);
}
return ans;
}
}