-
-
Notifications
You must be signed in to change notification settings - Fork 736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LeetCode] 54. Spiral Matrix #54
Comments
谢谢分享! FYI, 参考你的思路一写的, 不过没有用 class Solution {
public:
vector<int> spiralOrder(vector<vector<int> > &matrix) {
if (matrix.empty() || matrix[0].empty()) return {};
vector<int> res;
const int M = matrix.size();
const int N = matrix[0].size();
int cnt = M > N ? (N + 1) / 2 : (M + 1) / 2;
for (int i = 0; i < cnt; ++i) {
for (int col = i; col < N - i; ++col) {
res.push_back(matrix[i][col]);
}
for (int row = i+1; row < M - i; ++row) {
res.push_back(matrix[row][N-1-i]);
}
if (M > N
? ((N - i) * 2 - 1 == N)
: ((i + 1) * 2 - 1 == M)) {
break;
}
for (int col = N-i-2; col >= i; --col) {
res.push_back(matrix[M-1-i][col]);
}
for (int row = M-i-2; row >= i+1; --row) {
res.push_back(matrix[row][i]);
}
}
return res;
}
}; |
This problem can be solved by recursively rotating the matrix in counter-clockwise. class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
return matrix and list(matrix.pop(0)) + self.spiralOrder(list(zip(*matrix))[::-1]) C++ class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
if (matrix.empty())
return res;
// Add 1st row to result
int C = matrix[0].size();
for (int i = 0; i < C; ++i)
res.push_back(matrix[0][i]);
// Copy from 2nd row and rotate
vector<vector<int>> rotated;
if (matrix.size() > 1) {
for (int c = 0; c < C; ++c) {
rotated.push_back(vector<int>{});
for (int r = 1; r < matrix.size(); ++r)
rotated[c].push_back(matrix[r][C-c-1]);
}
}
// Recursive call
vector<int> res0 = spiralOrder(rotated);
// Combine results from recusive call
if (!res0.empty())
res.insert(res.end(), res0.begin(), res0.end());
return res;
}
};
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
请点击下方图片观看讲解视频
Click below image to watch YouTube Video
Given an
m x n
matrix
, return all elements of thematrix
in spiral order.Example 1:
Example 2:
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
这道题让我们搓一个螺旋丸,将一个矩阵按照螺旋顺序打印出来,只能一条边一条边的打印,首先要从给定的 mxn 的矩阵中算出按螺旋顺序有几个环,注意最中间的环可以是一个数字,也可以是一行或者一列。环数的计算公式是 min(m, n) / 2,知道了环数,就可以对每个环的边按顺序打印,比如对于题目中给的那个例子,个边生成的顺序是(用颜色标记了数字,Github 上可能无法显示颜色,请参见博客园上的帖子) Red -> Green -> Blue -> Yellow -> Black
1 2 3
4 5 6
7 8 9
定义 p,q 为当前环的高度和宽度,当p或者q为1时,表示最后一个环只有一行或者一列,可以跳出循环。此题的难点在于下标的转换,如何正确的转换下标是解此题的关键,可以对照着上面的 3x3 的例子来完成下标的填写,代码如下:
解法一:
如果觉得上面解法中的下标的转换比较难弄的话,也可以使用下面这种坐标稍稍简洁一些的方法。对于这种螺旋遍历的方法,重要的是要确定上下左右四条边的位置,那么初始化的时候,上边 up 就是0,下边 down 就是 m-1,左边 left 是0,右边 right 是 n-1。然后进行 while 循环,先遍历上边,将所有元素加入结果 res,然后上边下移一位,如果此时上边大于下边,说明此时已经遍历完成了,直接 break。同理对于下边,左边,右边,依次进行相对应的操作,这样就会使得坐标很有规律,并且不易出错,参见代码如下:
解法二:
若对上面解法中的多个变量还是晕的话,也可以使用类似迷宫遍历的方法,这里只要设定正确的遍历策略,还是可以按螺旋的方式走完整个矩阵的,起点就是(0,0)位置,但是方向数组一定要注意,不能随便写,开始时是要往右走,到了边界或者访问过的位置后,就往下,然后往左,再往上,所以 dirs 数组的顺序是 右->下->左->上。还需要一个 visited 数组来记录某个位置是否已经访问过,访问过值为1,否则为0,这样再判断新位置的时候,只要其越界了,或者是 visited 数组中的值为1了,就表明此时需要转弯了,到 dirs 数组中去取转向的 offset,得到新位置,注意这里的 dirs 数组中取是按循环数组的方式来操作,加1然后对4取余,按照这种类似迷宫遍历的方法也可以螺旋遍历矩阵,参见代码如下:
解法三:
Github 同步地址:
#54
类似题目:
Spiral Matrix II
Spiral Matrix III
Spiral Matrix IV
参考资料:
https://leetcode.com/problems/spiral-matrix/
https://leetcode.com/problems/spiral-matrix/discuss/20719/0ms-Clear-C%2B%2B-Solution
https://leetcode.com/problems/spiral-matrix/discuss/20599/Super-Simple-and-Easy-to-Understand-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)
(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)
喜欢请点赞,疼爱请打赏❤️~.~
微信打赏
|
Venmo 打赏
---|---
The text was updated successfully, but these errors were encountered: