题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
思路
边界条件参考这篇博客。个人认为本题目的核心考点在于边界条件的处理。遍历矩阵可以近似地视为周期遍历,即顺时针一圈作为一个“周期”,需要借助4个循环,这是问题解决的基本思路。之后,需要借助4个边界left、right、top和btm分别是左右上下边界,而且这是数组的实际边界!很明显,每次遍历完成后,需要一次“缩圈”的操作,即边界向中间靠拢。
最外层有一个大的循环,这个循环用于控制周期遍历的终止,很明显可以顺利执行的条件是left<right、top<btm。
最后就是特别麻烦的内部周期边界条件控制了。。。
- 从左向右这一个无论如何都要进行打印
- 从上到下,需要的边界是必须至少是两行才行,因此添加边界top<btm
- 从右到左,需要的边界是2的基础上,再保证至少2列,因此边界条件是top<btm && left<right
- 从下之上,需要的边界是至少2列,同时需要至少3行,因此边界条件是top+1<btm && left<right
编码时的边界条件处理还需要加强!!!!!
AC代码
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
vector<int>v;
if(matrix.empty()) {
return v;
}
int left = 0, right = matrix[0].size() - 1;
int top = 0, btm = matrix.size() - 1;
while(left <= right && top <= btm) {
for(int i = left; i <= right; ++i) {
v.push_back(matrix[top][i]);
}
if(top < btm) {
for(int i = top + 1; i <= btm; ++i) {
v.push_back(matrix[i][right]);
}
}
if(top < btm && left < right) {
for(int i = right - 1; i >= left; --i) {
v.push_back(matrix[btm][i]);
}
}
if(top + 1 < btm && left < right) {
for(int i = btm - 1; i >= top + 1; --i) {
v.push_back(matrix[i][left]);
}
}
++left;
--right;
++top;
--btm;
}
return v;
}
};