首页 > 代码库 > Leetcode:Spiral Matrix 螺旋矩阵
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]
.
解题分析:
这题就是 边界情况非常复杂
实际上就是 从外圈到内圈依次打印矩阵中的每一个圈
假设这个矩阵的行数为nRows,列数为nCols,我们每次从一个圈的左上角开始处理
设这个开始角坐标为 startX和startY(注意是坐标系中的坐标,不是矩阵中行列下标,因为矩阵A[i][j]对应着横坐标为j,纵坐标为i)
每处理一圈之后,下一圈的行列数分别减2,所以对于 startX和startY的循环终止应该是:nRows > 2 * startX && nCols > 2 * startY
我们计算出每次循环中的当前圈的长度rowLen和宽度colLen,并且计算出横坐标的最大值和纵坐标的最大值
然后分四步处理每一圈:
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; }};