【剑指Offer-画图让抽象问题形象化】面试题29:顺时针打印矩阵

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

思路

将矩阵按照从外向里以顺时针的顺序依次打印出每一个数字,就是从外向里一圈一圈地打印数字。例如,对上面的矩阵来说,矩阵形状为4x4,共打印2圈:第一圈起始于坐标(0,0),值为1;第二圈起始于坐标(1,1),值为6. 对一个5x5的矩阵来说,最内一圈起始点为(2, 2),对于一个6x6的矩阵来说,最内一圈的起点为(2,2)。我们发现当rows>start*2并且cols>start*2时循环结束,其中,rows,cols为矩阵的行列数,start为起始位置。

如上图所示,顺时针打印一圈分为4个步骤,但只有第1步从左到右横向打印是必须的,其他3步都不是必须的。当至少有两行,也就是终止行号大于起止行号的时候才需要第2步;当至少有两行两列时,也就是终止行号大于起止行号并且终止列号大于起止列号的时候才需要第3步;当终止行号比起始行号大于1并且起始列号大于终止列号时,才需要第4步。代码如下:

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        if(matrix.empty()){
            cout<<"";
            vector<int> empty;
            return empty;
        }
        
        int rows = matrix.size();
        int cols = matrix[0].size();
        
        int start = 0;
        vector<int> ans;
        while(rows>start*2 && cols>start*2){
            circle(matrix, rows, cols, start, ans);
            start++;
        }
        
        for(int i=0; i<ans.size(); i++){
            if(i==0)
                cout<<ans[i];
            else cout<<","<<ans[i];
        }
        return ans;
    }
    
    void circle(vector<vector<int> > matrix, int rows, int cols, int start, vector<int>& ans){
        int endRow = rows-1-start;
        int endCol = cols-1-start;
        
        for(int i=start; i<=endCol; i++)
            ans.push_back(matrix[start][i]);
        
        if(endRow-start>0){
            for(int i=start+1; i<=endRow; i++)
                ans.push_back(matrix[i][endCol]);
            if(endCol-start>0){
                for(int j=endCol-1; j>=start; j--)
                    ans.push_back(matrix[endRow][j]);
                if(endRow-start>1){
                    for(int k=endRow-1; k>start; k--)
                        ans.push_back(matrix[k][start]);
                }
            }
        }
    }
};
posted @ 2020-03-11 21:56  Flix  阅读(113)  评论(0编辑  收藏  举报