題目以下java
分析python
不難發現,按照順時針螺旋順序遍歷矩陣其實就只有四個方向:頂層行從左往右;右邊列從上到下;底層行從右往左;左邊列從下往上。遍歷完這四個方向以後就表示已經遍歷完了一圈,下一圈也一樣是這四個方向,只是初始位置和結束位置會在每一輪遍歷以後發生變化。數組
下面介紹兩種方法,思想基本一致,不一樣之處是對邊界的判斷和位置的移動。app
方法一ide
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; }
方法二 spa
設數組有R行和C列。 seen[r] [c] = ture表示先前訪問過第r行和第c列的元素。 咱們當前的位置是(r,c),面向方向di,咱們想要訪問R x C個所有元素。圖片
當咱們在矩陣中移動時,咱們的候選下一個位置是(cr,cc)。 若是候選位置處於矩陣的邊界而且看不見(即seen[cr][cc] = false),那麼它就成了咱們的下一個位置; 不然,咱們的下一個位置是順時針轉彎後的位置。it
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實現
class
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