题目如下
分析
不难发现,按照顺时针螺旋顺序遍历矩阵其实就只有四个方向:顶层行从左往右;右边列从上到下;底层行从右往左;左边列从下往上。遍历完这四个方向之后就表示已经遍历完了一圈,下一圈也同样是这四个方向,只是初始位置和结束位置会在每一轮遍历之后发生变化。
下面介绍两种方法,思想基本一致,不同之处是对边界的判断和位置的移动。
方法一
public class SpiralMatrix {
public static List<Integer> spiralMatrixOlder(int[][] matrix) {
List<Integer> res = new ArrayList<Integer>();
if(matrix.length == 0)
return res;
int rowBegin = 0;
int colBegin = 0;
int rowEnd = matrix.length - 1; //行
int colEnd = matrix[0].length - 1; //列
/*
* Time Complexity: O(N)
* Space Complexity:O(N)*/
while(rowBegin <= rowEnd && colBegin <= colEnd){
//底层行从左往右
for(int i = colBegin;i <= colEnd;i++) {
res.add(matrix[rowBegin][i]);
}
rowBegin++; //处理完一行后往下移一行
//右边列从上往下
for(int i = rowBegin ;i <= rowEnd;i++) {
res.add(matrix[i][colEnd]);
}
colEnd--; //处理完一列往前移一列
//底层行从右往左
if(rowBegin <= rowEnd) {
for(int j = colEnd;j>=colBegin;j--){
res.add(matrix[rowEnd][j]);
}
rowEnd--;
}
//左边列从下往上
if(colBegin <= colEnd) {
for(int j = rowEnd;j >= rowBegin ; j--) {
res.add(matrix[j][colBegin]);
}
colBegin++;
}
}
return res;
}
方法二
设数组有R行和C列。 seen[r] [c] = ture表示先前访问过第r行和第c列的元素。 我们当前的位置是(r,c),面向方向di,我们想要访问R x C个全部元素。
当我们在矩阵中移动时,我们的候选下一个位置是(cr,cc)。 如果候选位置处于矩阵的边界并且看不见(即seen[cr][cc] = false),那么它就成了我们的下一个位置; 否则,我们的下一个位置是顺时针转弯后的位置。
public class SpiralMatrixBter {
public List<Integer> spiralMatrixOlder(int [][] matrix) {
List<Integer> res = new ArrayList<Integer>();
if(matrix.length == 0) return res;
int rowLen = matrix.length;
int colLen = matrix[0].length;
boolean[][] seen = new boolean[rowLen][colLen];
//顶层行遍历时:row+=0,col+=1
//右边列遍历时:row+=1,col+=0
//底层行遍历时:row+=0,col+=-1
//左边列遍历时:row+=-1,col+=0
//把上面的信息存储到数组中
int[] dr = {0,1,0,-1};
int[] dc = {1,0,-1,0};
int row = 0;
int col = 0;
int di = 0;
for(int i = 0;i < rowLen*colLen;i++) {
res.add(matrix[row][col]);
seen[row][col] = true; //表示此节点已被读取
int cr = row + dr[di];
int cc = col + dc[di];
if(cr >= 0 && cr <rowLen && cc >= 0 && cc < colLen && !seen[cr][cc]) {
row = cr;
col = cc;
}else{
di = (di + 1) % 4;
row += dr[di];
col += dc[di];
}
}
return res;
}
Python实现
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
ret = []
while matrix:
ret += matrix.pop(0)
if matrix and matrix[0]:
for row in matrix:
ret.append(row.pop())
if matrix:
ret += matrix.pop()[::-1]
if matrix and matrix[0]:
for row in matrix[::-1]:
ret.append(row.pop(0))
return ret
转载于:https://blog.51cto.com/acevi/2141009