Leetcode:Spiral Matrix 螺旋矩阵

Spiral Matrix

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.



For example,

Given the following matrix:

 

[

 [ 1, 2, 3 ],

 [ 4, 5, 6 ],

 [ 7, 8, 9 ]

]

 

You should return [1,2,3,6,9,8,7,4,5].

 

解题分析:

这题就是 边界情况非常复杂

实际上就是 从外圈到内圈依次打印矩阵中的每一个圈

Leetcode:Spiral Matrix 螺旋矩阵 

 

假设这个矩阵的行数为nRows,列数为nCols,我们每次从一个圈的左上角开始处理

设这个开始角坐标为 startX和startY(注意是坐标系中的坐标,不是矩阵中行列下标,因为矩阵A[i][j]对应着横坐标为j,纵坐标为i)

每处理一圈之后,下一圈的行列数分别减2,所以对于 startX和startY的循环终止应该是:nRows > 2 * startX && nCols > 2 * startY

 

我们计算出每次循环中的当前圈的长度rowLen和宽度colLen,并且计算出横坐标的最大值和纵坐标的最大值

Leetcode:Spiral Matrix 螺旋矩阵

然后分四步处理每一圈:

1. 从左往右,打印上边一行,这时候是没有if语句判断的,因为无论如何至少可以前进一步

2. 从上往下,打印右边一列,这时候需要 endY > startY,也就是矩形宽度>=2, 如果endY == startY,表示只有一行,没有列元素打印.注意i=startY +1开始

3. 从右往左,打印下边一行,这时候需要 endX > startX && endY > startY,也就是小矩形长度和宽度都必须>=2,注意i=endX - 1开始

长度>=2确保可以从右往左开始打印,宽度>=2确保存在下边这一行

4. 从下往上,打印左边一列,这时候需要 endX > startX && endY > startY,即当前小矩形至少有2行2列,注意i = endY - 1开始,并且 i >= startY - 1(防止重复打印)

class Solution {

public:

    vector<int> spiralOrder(vector<vector<int> > &matrix) {

        vector<int> result;

        int nRows = matrix.size();

        if (nRows == 0) return result;

        int nCols = matrix.at(0).size();

        result.reserve(nRows * nCols);

        

        int startX = 0;

        int startY = 0;

        

        while (nRows > 2 * startX  && nCols > 2 * startY) {

            PrintNumbers(matrix, startX, startY, result);

            ++startX;

            ++startY;

        }

        return result;

        

    }

        void PrintNumbers(vector<vector<int>>& matrix, int startX, int startY, vector<int>& result) {

            assert(startX >= 0 && startY >= 0);

            int nRows = matrix.size();

            int nCols = matrix.at(0).size();

            

            int rowLen = nRows - 2 * startX; // 当前矩形的长度

            int colLen = nCols - 2 * startY; // 当前矩形的宽度

            

            int endX = startX + colLen - 1;  // endX - startX + 1 = colLen X为横坐标

            int endY = startY + rowLen - 1;  // endY - startY + 1 = rowLen Y为纵坐标

            

            // 1. 从左往右

            for (int i = startX; i <= endX; ++i) {

                result.push_back(matrix.at(startY).at(i));

            }

            

            // 2. 从上往下

            if (endY > startY) {

                for (int i = startY + 1; i <= endY; ++i) {

                    result.push_back(matrix.at(i).at(endX));

                }

            }

            

            // 3. 从右往左

            if (endX > startX && endY > startY) {

                for (int i = endX - 1; i >= startX; --i) {

                    result.push_back(matrix.at(endY).at(i));

                }

            }

            

            // 4. 从下往上

            if (endX > startX && endY > startY) {

                for (int i = endY - 1; i >= startY + 1; --i) {

                    result.push_back(matrix.at(i).at(startX));

                }

            }

        }

};

 

Spiral Matrix II

Given an integer n, generate a square matrix filled with elements from 1 to n^2 in spiral order.



For example,

Given n = 3,



You should return the following matrix:

 

[

 [ 1, 2, 3 ],

 [ 8, 9, 4 ],

 [ 7, 6, 5 ]

]

 

解题分析:

我们解决了上一题,这一题就很轻松了,而且题目中说明始终是一个方阵,所以 行和列数相等,startX == startY, endX == endY

直接按照打印的顺序填充矩阵即可

class Solution {

public:

    vector<vector<int> > generateMatrix(int n) {

        assert(n >= 0);

        vector<vector<int>> result(n, vector<int>(n, 0));

        

        

        int val = 1;

        int start = 0;

        

        for (int start = 0; start * 2 < n; ++start) {

            int len = n - 2 * start;

            int end = start + len - 1;

    

            // 1. 从左往右

            for (int i = start; i <= end; ++i) {

                result.at(start).at(i) = val++;

            }

            

            // 2. 从上往下

            if (end > start) {

                for (int i = start + 1; i <= end; ++i) {

                    result.at(i).at(end) = val++;

                }

            }

            

            // 3. 从右往左

            if (end > start) {

                for (int i = end - 1; i >= start; --i) {

                    result.at(end).at(i) = val++;

                }

            }

            

            // 4. 从下往上

            if (end > start) {

                for (int i = end - 1; i >= start + 1; --i) {

                    result.at(i).at(start) = val++;

                }

            }

        }

        return result;

    }

};

 

你可能感兴趣的:(LeetCode)