剑指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; } };

 

posted @ 2019-07-28 19:14  黑凤梨  阅读(114)  评论(0编辑  收藏  举报