剑指Offer-顺时针打印矩阵(难)

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.

思路分析

这道题我没有一个正确的思路,因此想不出如何做。直接参考了《剑指Offer》一书。

当我们遇到一个复杂问题的时候,可以用图形来帮助思考。由于是以从外圈到内圈的顺序依次打印的,所以我们可以把矩阵想象成若干个圈。我们可以用一个循环来打印矩阵,每次打印矩阵的一个圈。接着,我参考了 https://www.nowcoder.com/profile/6606749/codeBookDetail?submissionId=15814779 的写法。下面是对这道题解法的详细说明。感觉有点混乱啊!!!

class Solution{
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        vector<int> num;
        int rows = matrix.size();
        int cols = matrix[0].size();
        int circles = ((rows<cols ?: rows:cols)-1)/2+1; //求打印圈数

        for (int i=0; i<circles; i++){
            // 从左往右打印
            for(int j=i; j<cols-i; j++){
                num.push_back(matrix[i][j]);
            }
            // 从上往下打印
            for(int j=i+1; j<rows-i; j++){ //最后一行为rows-i-1
                num.push_back(matrix[j][cols-i-1]);
            }
            // 从右往左打印,其中(rows-i-1!=i)避免重复打印
            for(int j=cols-i-2; (j>=i)&&(rows-i-1!=i); j--){
                num.push_back(matrix[rows-i-1][j]);
            }
            // 从下往上打印
            for(int j=rows-i-2; (j>=i+1)&&(i!=cols-i-1); j--){
                num.push_back(matrix[j][i]);
            }
        }
        return num;
    }
}

其中rows-i-1!=i与cols-i-1!=i的限制就是单行或单列只打印一次,这个判断条件要特别注意。这道题没有什么特别的技巧,要注意的点就是确定for循环的条件。