剑指offer(19): 顺时针打印矩阵
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
分析思路: 输入矩阵可能是任意矩形,长宽哪一个更大不确定。 每一次输出最外圈,输出起点分别为(0,0),(1,1),(2,2)....(n,n)... 每一圈分四次输出,按顺时针方向依次为: 上边 →(row不变, col逐渐增加到最大), 右边 ↓(col不变, row逐渐增加到最大) ,下边 ←(row不变, col逐渐减小到最小),左 ↑(col不变,row逐渐减小到最小)。设置变量代表未输出的边数(row_length 和col_length), 任意一个为0就说明输出完毕。 输出的圈每次缩小,都要注意边界,不要超出取值范围。尤其注意当前所在行数和列数,以及坐标的变动。
class Solution { public: vector<int> printMatrix(vector<vector<int> > matrix) { vector<int> result; if(matrix.empty()) return result; int row_length = matrix.size(); if(row_length == 1) return matrix[0]; int col_length = matrix[0].size(); int start_row = 0, start_col = 0; while(row_length || col_length){ int current_row = start_row, current_col = start_col;
// 每一次输出一圈,开头的坐标为(0,0),(1,1)....
// 输出上边→(row不变, col逐渐增加到最大) for(int j = 0; j < col_length; j++){ result.push_back(matrix[current_row][current_col++]); } current_col--; // 越界,通过自减恢复 row_length--; // 已经打印完一行 if(!row_length) break; current_row++; // 从右上角的坐标往下移动一格
// 输出右边 ↓(col不变, row逐渐增加到最大) for(int i = 0; i < row_length; i++){ result.push_back(matrix[current_row++][current_col]); } current_row--; // 越界,恢复 col_length--; // 打印完一列 if(!col_length) break; current_col--;
// 下边 ←(row不变, col逐渐减小到最小) for(int j = 0; j < col_length; j++){ result.push_back(matrix[current_row][current_col--]); } current_col++; row_length--; if(!row_length) break; current_row--;
// 左 ↑(col不变,row逐渐减小到最小) for(int i = 0; i < row_length; i++){ result.push_back(matrix[current_row--][current_col]); } current_row++; col_length--; if(!col_length) break;
// 下一圈起点 start_row++; start_col++; } return result; } };