LeetCode 54. 螺旋矩阵
题目描述
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
css
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
css
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/spiral-matrix 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
和 上一期 螺旋矩阵差不多,这个是让我么输出,而上次是让我们构造,还是按照螺旋矩阵模拟即可,先从左到右,在从上到下,再从右到左,再从下到上。
不过这里的矩阵行和列不相同了,可能会出现不成环的情况,那么最后会留一列或一行出来,这里借用大佬一张图:
然后我们需要提前跳出去一下,就是避免重复计算,总数够了直接跳出去。注意下面代码 break
。只能放在那里,因为遍历顺序,如果最后留下一行的话,需要从左到右遍历,此时 top > bottom
。如果最后留下一列的话,需要从上到下遍历,此时 left > right
。
javascript
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function (matrix) {
if (!matrix.length) return [];
let n = matrix.length;
let m = matrix[0].length;
let total = n * m;
let top = 0,
bottom = n - 1;
let left = 0,
right = m - 1;
let res = [];
while (res.length < total) {
for (let i = left; i <= right; i++) res.push(matrix[top][i]); // 从左到右
top++;
for (let i = top; i <= bottom; i++) res.push(matrix[i][right]); // 从上到下
right--;
/* 因为n 和 m 不相同的时候,最后可能会留一列或一行,避免重复计算,总数够了直接跳出去 */
if (res.length === total) break;
for (let i = right; i >= left; i--) res.push(matrix[bottom][i]); // 从右到左
bottom--;
for (let i = bottom; i >= top; i--) res.push(matrix[i][left]); // 从下到上
left++;
}
return res;
};
cpp
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if (matrix.empty()) return {};
int n = matrix.size();
int m = matrix[0].size();
int total = n * m;
int top = 0, bottom = n - 1;
int left = 0, right = m - 1;
vector<int> res;
while (res.size() < total) {
for (int i = left; i <= right; i++) res.push_back(matrix[top][i]); // 从左到右
top++;
for (int i = top; i <= bottom; i++) res.push_back(matrix[i][right]); // 从上到下
right--;
/* 因为n 和 m 不相同的时候,最后可能会留一列或一行,避免重复计算,总数够了直接跳出去 */
if (res.size() == total) break;
for (int i = right; i >= left; i--) res.push_back(matrix[bottom][i]); // 从右到左
bottom--;
for (int i = bottom; i >= top; i--) res.push_back(matrix[i][left]); // 从下到上
left++;
}
return res;
}
};
java
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
if (matrix.length == 0) return new ArrayList<>();
int n = matrix.length;
int m = matrix[0].length;
int total = n * m;
int top = 0, bottom = n - 1;
int left = 0, right = m - 1;
List<Integer> res = new ArrayList<>();
while (res.size() < total) {
for (int i = left; i <= right; i++) res.add(matrix[top][i]); // 从左到右
top++;
for (int i = top; i <= bottom; i++) res.add(matrix[i][right]); // 从上到下
right--;
/* 因为n 和 m 不相同的时候,最后可能会留一列或一行,避免重复计算,总数够了直接跳出去 */
if (res.size() == total) break;
for (int i = right; i >= left; i--) res.add(matrix[bottom][i]); // 从右到左
bottom--;
for (int i = bottom; i >= top; i--) res.add(matrix[i][left]); // 从下到上
left++;
}
return res;
}
}
python
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix: return []
n = len(matrix)
m = len(matrix[0])
total = n * m
top = 0
bottom = n - 1
left = 0
right = m - 1
res = []
while len(res) < total:
for i in range(left, right + 1): res.append(matrix[top][i]) # 从左到右
top += 1
for i in range(top, bottom + 1): res.append(matrix[i][right]) # 从上到下
right -= 1
if len(res) == total: break
for i in range(right, left - 1, -1): res.append(matrix[bottom][i]) # 从右到左
bottom -= 1
for i in range(bottom, top - 1, -1): res.append(matrix[i][left]) # 从下到上
left += 1
return res
javascript
学如逆水行舟,不进则退