螺旋矩阵
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例2
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
思路一
顺时针旋转相当于转置加上上下反转。
利用python的 库函数每次顺时针旋转输出第一行,就可以得到一个顺时针旋转的序列
使用numpy 解决
代码如下:
class Solution:
def spiralOrder(self, matrix):
import numpy as np
res = []
while matrix:
res +=list(matrix.pop(0)) # 这里不能使用append 不然得到的不是一个一维数组
matrix = np.array(matrix)
matrix = np.transpose(matrix) # 对numpy数组进行转置
matrix = matrix[::-1]
matrix = list(matrix)
return res
使用zip函数解决
利用zip函数的功能可以很好地解决这个问题
zip 函数实现对列表的转置,[::-1]实现对矩阵的上下反转
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
res = []
while matrix:
res += matrix.pop(0)
matrix = list(map(list, zip(*matrix)))[::-1] # zip +[::-1]
return res
逐层模拟(C++实现)
每次输出螺旋矩阵的一层,同时判断是否有四条边
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> ans;
if(matrix.size()==0) return ans; // 当矩阵长度为0的时候直接返回
int length_r = matrix.size();
int length_c = matrix[0].size();
int r1= 0 ;int r2 =length_r-1 ;
int c1 = 0 ;int c2 = length_c-1 ;
int i =0 ;int j =0;
while( r1 <= r2 && c1 <=c2){ // 每次遍历最外面的一层
for( j = c1 ;j<=c2;j++) ans.push_back(matrix[r1][j]);
for( i =r1+1 ;i<=r2 ;i++) ans.push_back(matrix[i][c2]);
// r1<r2&& c1<c2 代表着这个矩阵有四条边,如果存在四条边那么需要输出下面和左边的那一层
if(r1 < r2 && c1 <c2){
for ( j = c2 -1 ; j>c1 ;j--) ans.push_back(matrix[r2][j]); // 每次输出都要注意边界的值
for ( i = r2 ; i>r1 ;i--) ans.push_back(matrix[i][c1]);
}
// 在一层输入完之后更新矩阵的大小
r1+=1;
r2 -=1;
c1 +=1;
c2-=1;
}
return ans;
}
};