LeetCodeHot100---螺旋矩阵---一题两解
给你一个
m
行n
列的矩阵matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
方法1:模拟(时间 O(mn),击败100%)
class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> ans = new ArrayList<>();int m = matrix.length, n = matrix[0].length;int[][] directions = {{0,1},{1,0},{0,-1},{-1,0}};boolean[][] visited = new boolean[m][n];int totalCount = m * n;int row=0, col=0, direction=0;for(int i=0;i<totalCount;i++){ans.add(matrix[row][col]);visited[row][col] = true;int nextRow=row+directions[direction][0];int nextCol=col+directions[direction][1];if(nextRow<0 ||nextRow>=m ||nextCol<0|| nextCol>=n || visited[nextRow][nextCol]){direction=(direction+1)%4;}row=row+directions[direction][0];col=col+directions[direction][1];}return ans; }
}
模拟方法,就是从 matrix[0][0] 开始,一步一步模拟走的方向。
既然是模拟走的方向,我们需要解决两个问题:1、怎么让他走?2、要越过边界的时候怎么阻止?
对于问题1,我们可以在走的时候,将当前位置看作 matrix[row][col],当他要往右走并且不会越界的时候,row 不变,col+1,当他要往下走并不越界的时候,row+1,col 不变,我们可以通过一个二维数组来完成。
走路过程是:右——下——左——上——右 这样循环,那么二维数组就可以设置成 int[][] directions = {{0,1}, {1,0}, {0.-1}, {-1,0}},这样取 directions[0],然后加到 row 和 col 上,就可以出现 row 不变,col+1 的情况,也就是向右走,然后第二个就是向下走,之后就可以通过 direction = (direction + 1) % 4,获得当前要往哪走。
知道往哪走,我们要确保不越界的两种情况:1、row < 0, row >= m, col < 0, col >= n;2、当前位置没有被访问过。
情况1直接写在 if 循环就好,情况2我们可以采用一个二维的 boolean 数组 visited,当访问过之后,visited[row][col] = true,然后 if 循环再判断当前位置是否为 true 就好了。
方法2:逐层模拟:
class Solution {public List<Integer> spiralOrder(int[][] matrix) {int m = matrix.length, n = matrix[0].length;List<Integer> ans = new ArrayList<Integer>();int top=0, bottom=m-1, left=0, right=n-1;while(top<=bottom && left<=right){for(int i=left;i<=right;i++){ans.add(matrix[top][i]);}top++;for(int i=top;i<=bottom;i++){ans.add(matrix[i][right]);}right--;if(top<=bottom && left<=right){for(int i=right;i>=left;i--){ans.add(matrix[bottom][i]);}}bottom--;if(top<=bottom && left<=right){for(int i=bottom;i>=top;i--){ans.add(matrix[i][left]);}}left++;}return ans;}
}
一层一层往里模拟,最后得到答案。
左上 matrix[top][left],右上 matrix[top][right],
左下 matrix[bottom][left],右下 matrix[bottom][right].