1 模拟过程
“模拟过程题”通常指的是那些要求编程者通过编写代码来“模拟”或重现某个过程、系统或规则的题目。这类题目往往不涉及复杂的数据结构或高级算法,而是侧重于对给定规则的精确执行和逻辑的清晰表达。
其中螺旋遍历矩阵的题目就是一类典型的模拟过程题,需要精心设计循环和边界条件来控制遍历的方向和路径。
2 例题
题目描述
给你一个 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
题目来源
- 54. 螺旋矩阵 - 力扣(LeetCode)
3 解法
3.1 解题思路
(1)空值处理,matrix 为空时,直接返回空列表
(2)初始化边界值 left、right、top、bottom 以及用于打印结果的列表 result
(3)循环打印矩阵,每个循环按四个方向打印,每个方向打印完成后边界内缩 1,满足终止条件则退出循环,输出 result
打印方向 | 边界收缩 | 打印终止条件 |
---|---|---|
从左到右 | top 加 1 | top > bottom |
从上到下 | right 减 1 | left > right |
从右到左 | bottom 减 1 | top > bottom |
从下到上 | left 加 1 | left > right |
3.2 Java 代码实现
public List<Integer> spiralOrder(int[][] matrix) {
// 空值处理
if (matrix == null || matrix.length == 0) {
return new ArrayList<>();
}
// 初始化边界值
int left = 0;
int right = matrix[0].length - 1;
int top = 0;
int bottom = matrix.length - 1;
// 初始化结果集
List<Integer> result = new ArrayList<>();
// 循环打印矩阵
while (true) {
// 从左到右
for (int i = left; i <= right; i++) {
result.add(matrix[top][i]);
}
// top 边界内缩 1,终止条件:top > bottom
if (++top > bottom) {
break;
}
// 从上到下
for (int i = top; i <= bottom; i++) {
result.add(matrix[i][right]);
}
// right 边界内缩 1,终止条件:left > right
if (--right < left) {
break;
}
// 从右到左
for (int i = right; i >= left; i--) {
result.add(matrix[bottom][i]);
}
// bottom 边界内缩 1,终止条件:top > bottom
if (--bottom < top) {
break;
}
// 从下到上
for (int i = bottom; i >= top; i--) {
result.add(matrix[i][left]);
}
// left 边界内缩 1,终止条件:left > right
if (++left > right) {
break;
}
}
return result;
}
4 相关题目(题目来源:Leetcode)
4.1 螺旋矩阵 II
4.1.1 题目描述
给你一个正整数 n
,生成一个包含 1
到 n^2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20
题目来源
- 59. 螺旋矩阵 II - 力扣(LeetCode)
4.1.2 解题思路
(1)初始化一个 n x n 的矩阵 matrix 、边界值 left、right、top、bottom 以及填充元素值 num
(2)循环填充矩阵,每个循环按四个方向填充,每填充一个数字 num 自增 1,每个方向填充完成后边界内缩 1
填充方向 | 边界收缩 |
---|---|
从左到右 | top 加 1 |
从上到下 | right 减 1 |
从右到左 | bottom 减 1 |
从下到上 | left 加 1 |
(3)终止条件 num > n * n 即所有元素填充完毕,输出 matrix
4.1.3 Java 代码实现
public int[][] generateMatrix(int n) {
// 初始化矩阵以及边界值
int[][] matrix = new int[n][n];
int left = 0;
int right = n - 1;
int top = 0;
int bottom = n - 1;
// 填充元素值
int num = 1;
// 循环填充矩阵
while (num <= n * n) {
// 从左到右
for (int i = left; i <= right; i++) {
matrix[top][i] = num++;
}
// top 边界内缩 1
top++;
// 从上到下
for (int i = top; i <= bottom; i++) {
matrix[i][right] = num++;
}
// right 边界内缩 1
right--;
// 从右到左
for (int i = right; i >= left; i--) {
matrix[bottom][i] = num++;
}
// bottom 边界内缩 1
bottom--;
// 从下到上
for (int i = bottom; i >= top; i--) {
matrix[i][left] = num++;
}
// left 边界内缩 1
left++;
}
return matrix;
}