给定一个包含 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
输入:[[ 6,4,1 ], [ 7,8,9 ]]
输出: [6,4,1,9,8,7]
解题思路:
把矩阵看成若干个顺时针方向的圈组成。每添加完一个圈将范围向内缩一圈,继续添加,直到添加完毕。
注意边界条件,当矩形不是正方形时,添加到最后可能只剩一列或一行,需要单独处理。
public class Solution {
/**
* @param matrix: a matrix of m x n elements
* @return: an integer list
*/
public List<Integer> spiralOrder(int[][] matrix) {
// write your code here
ArrayList<Integer> result = new ArrayList<>();
if(matrix == null || matrix.length == 0){
return result;
}
//定位4点
int top = 0;
int bottom = matrix.length - 1;
int left = 0;
int right = matrix[0].length - 1;
//定位范围
int n = matrix.length;
int m = matrix[0].length;
while(n > 1 && m > 1){
for(int i = 0; i < m - 1; i++)
result.add(matrix[top][left + i]);
for(int i = 0; i < n - 1; i++)
result.add(matrix[top + i][right]);
for(int i = 0; i < m - 1; i++)
result.add(matrix[bottom][right - i]);
for(int i = 0; i < n - 1; i++)
result.add(matrix[bottom - i][left]);
//一圈添加完毕
top++;
left++;
bottom--;
right--;
n -= 2;
m -= 2;
}
//最后还剩一列
if(left == right){
for(int i = top; i <= bottom; i++)
result.add(matrix[i][left]);
return result;
}
//最后还剩一行
if(top == bottom){
for(int i = left; i <= right; i++)
result.add(matrix[top][i]);
return result;
}
return result;
}
}
二刷:
public class Solution {
/**
* @param matrix: a matrix of m x n elements
* @return: an integer list
*/
public List<Integer> spiralOrder(int[][] matrix) {
// write your code here
List<Integer> res = new ArrayList<>();
if(matrix == null || matrix.length == 0)
return res;
int i = 0, j = -1; //遍历元素,初始化j为-1,因为下面遍历会首先+1
int row = matrix.length;
int col = matrix[0].length;
boolean[][] isVisited = new boolean[row][col]; //记录当前元素是否被遍历过
int times = 0; //记录添加次数
while(times < row*col){ //当添加次数少于元素总和时,说明还没添加完
while(j+1 < col && !isVisited[i][j+1]){ //向左
isVisited[i][j+1] = true;
res.add(matrix[i][++j]);
times++;
}
while(i+1 < row && !isVisited[i+1][j]){ //向下
isVisited[i+1][j] = true;
res.add(matrix[++i][j]);
times++;
}
while(j-1 >= 0 && !isVisited[i][j-1]){ //向右
isVisited[i][j-1] = true;
res.add(matrix[i][--j]);
times++;
}
while(i-1 >= 0 && !isVisited[i-1][j]){ //向上
isVisited[i-1][j] = true;
res.add(matrix[--i][j]);
times++;
}
}
return res;
}
}