螺旋矩阵
思路
螺旋矩阵1,2: 1) 按顺时针方向模拟 定义方向=> 初始方向递进, 遇到转折点变换方向, 遍历全部元素 2) 按层模拟: 确定层数 => 处理层 => 处理非圈
题解
// [54. 螺旋矩阵](https://leetcode-cn.com/problems/spiral-matrix/)
// 这样模拟更简洁, 更加不容易出错. 但是增加了空间复杂度used数组
class Solution1 {
public List<Integer> spiralOrder(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
int[][] direction = new int[][]{{0, 1}, {1, 0}, {0, - 1}, {-1, 0}}; // 四个方向的循环
int dIndex = 0; // 方向索引,默认是direction[0] 也就是从左到右
int[][] used = new int[m][n]; // 记录遍历过位置, 用于判断是否转变方向
List<Integer> result = new LinkedList<>();
// 1. 遍历全部元素
int r = 0;
int c = 0;
for (int i = 0; i < m * n; i++) {
// 2. 访问当前元素
result.add(matrix[r][c]);
used[r][c] = 1;
// 3. 转变方向(判断到达转折点)
int nextR = r + direction[dIndex][0], nextC = c + direction[dIndex][1];
if (nextR < 0 || nextR >= m || nextC < 0 || nextC >= n || used[nextR][nextC] == 1) dIndex = (dIndex + 1) % 4;
// 跟新step
r = r + direction[dIndex][0];
c = c + direction[dIndex][1];
}
return result;
}
}
// 模拟循环过程, 1)方形: 奇数, 偶数, 2)非方形: 取决于短边 => 定义圈数量
class Solution2 {
public List<Integer> spiralOrder(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
int loop = Math.min(m, n) / 2;
List<Integer> result = new LinkedList<>();
// 1. 对圈进行处理: 区间保持[), loop = 2
for (int k = 0; k < loop; k++) {
// 左->右
for (int j = k; j < k + n - 1 - 2 * k; j++) {
result.add(matrix[k][j]);
}
// 上->下
for (int i = k; i < k + m - 1 - 2 * k; i++) {
result.add(matrix[i][k + n - 1 - 2 * k]);
}
// 右->左
for (int j = n - 1 - k; j > k; j--) {
result.add(matrix[m - 1 - k][j]);
}
// 下->上
for (int i = m - 1 - k; i > k; i--) {
result.add(matrix[i][k]);
}
}
// 2. 非圈进行处理: i / 2,
if (n == m && m % 2 != 0) result.add(matrix[m / 2][n / 2]);
if (n > m && m % 2 != 0) {
for (int j = loop; j < loop + n - m + 1; j++) result.add(matrix[loop][j]); // 往右走
}
if (n < m && n % 2 != 0){
for (int i = loop; i < loop + m - n + 1; i++) result.add(matrix[i][loop]); // 往下走
}
// 3. 返回结果
return result;
}
}