【算法系列-数组】螺旋矩阵(模拟)
文章目录
- 【算法系列-数组】螺旋矩阵(模拟)
- 1. 螺旋矩阵II(LeetCode 59)
- 1.1 思路分析🎯
- 1.2 解题过程🎬
- 1.3 代码示例🌰
- 2. 螺旋矩阵(LeetCode 54)
- 2.1 思路分析🎯
- 2.2 解题过程🎬
- 2.3 代码示例🌰
- 3. 螺旋遍历二维数组(剑指Offer 146)
- 3.1 思路分析🎯
- 3.2 代码示例🌰
1. 螺旋矩阵II(LeetCode 59)
【题目链接】
1.1 思路分析🎯
这道题通过模拟解题,同时需要遵守循环不变量,明确好每一(行/列)走完时的边界值,如下:
- 左上到右上,不包括右上,右上交给下一轮开头;
- 右上到右下,不包括右下,右下交给下一轮开头;
- 右下到左下,不包括左下,左下交给下一轮开头;
- 左下到左上,不包括左上,此时一圈已结束;
若传进来的n为奇数,则最后中间都会剩一个空,此时将直接赋值arr [n / 2][n / 2] = count即可;
1.2 解题过程🎬
初始化 x为矩阵行首,y为矩阵列首 offset用来计算每次拐弯时的边界值,即每次循环都不取每行/每列的边界值,交给下一层循环作起始值,每一圈结束后offset需要 + 1; 圈数 q = n / 2,每次循环结束q–;
进入while循环,表示开始新一圈的赋值,之后通过四个for循环对矩阵的四条边进行赋值,直到四次循环结束,矩阵行首 x + 1,矩阵列首 y + 1, offset + 1,圈数 q - 1,重复上述过程直到q 为 0; 若 n 为 奇数,表示最后矩阵中间会单独剩下一个位,直接赋值即可
1.3 代码示例🌰
class Solution {
public int[][] generateMatrix(int n) {
int x = 0;
int y = 0;
int[][] arr = new int[n][n];
int offset = 1;
int count = 1;
int i = 0, j = 0;
int q = n / 2, mid = n / 2;
while (q > 0) {
j = y;
i = x;
for (;j < n - offset;j++) {
arr[i][j] = count++;
}
for (;i < n - offset;i++) {
arr[i][j] = count++;
}
for (;j > y;j--) {
arr[i][j] = count++;
}
for (;i > x;i--) {
arr[i][j] = count++;
}
x++;
y++;
offset++;
q--;
}
if (n % 2 == 1) {
arr[mid][mid] = count++;
}
return arr;
}
}
2. 螺旋矩阵(LeetCode 54)
【题目链接】
2.1 思路分析🎯
这道题的解法与上道题目(螺旋矩阵II)存在一些区别,区别在于这道题:每次循环都取每行/每列最后的边界值,即做到每一轮的最后边界值在下一轮的开始都不会使用:
2.2 解题过程🎬
定义好初始数据:
l: 最左边界值
r: 最右边界值
t: 最上边界值
b:最下边界值
之后进入循环,在循环中依次进行理论循环移动:
从左到右:让索引 i = l,从左到右遍历直到 i > r,结束此轮遍历,同时 ++t,最上边界值向下移动一格并进行判断,若 t > b 则退出主循环;
从上到下:让索引 i = t,从上到下遍历直到 i > b,结束此轮遍历,同时 --r,最右边界值向左移动一格并进行判断,若 r < l 则退出主循环;
从右到左:让索引 i = r,从右到左遍历直到 i < l,结束此轮遍历,同时 --b,最下边界值向上移动一格并进行判断,若 b < t 则退出主循环;
从下到上:让索引 i = b,从下到上遍历直到 i < t,结束此轮遍历,同时 ++l,最左边界值向右移动一格并进行判断,若 l > r 则退出主循环;
直到主循环退出,返回收集好数据的列表即可
2.3 代码示例🌰
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
if (matrix.length == 0) {
return new ArrayList<Integer>();
}
int t = 0, b = matrix.length - 1, l = 0, r = matrix[0].length - 1;
List<Integer> list = new ArrayList<>();
while (true) {
for (int i = l;i <= r;i++) {
list.add(matrix[t][i]);
}
if (++t > b) {
break;
}
for (int i = t;i <= b;i++) {
list.add(matrix[i][r]);
}
if (--r < l) {
break;
}
for (int i = r;i >= l;i--) {
list.add(matrix[b][i]);
}
if (--b < t) {
break;
}
for (int i = b;i >= t;i--) {
list.add(matrix[i][l]);
}
if (++l > r) {
break;
}
}
return list;
}
}
3. 螺旋遍历二维数组(剑指Offer 146)
【题目链接】
3.1 思路分析🎯
这道题的解题思路与上道题(螺旋矩阵)基本一致
3.2 代码示例🌰
class Solution {
public int[] spiralArray(int[][] array) {
if (array.length == 0) {
return new int[0];
}
int t = 0, b = array.length - 1, l = 0, r = array[0].length - 1;
int[] arr = new int[(b + 1) * (r + 1)];
int x = 0;
while (true) {
for (int i = l;i <= r;i++) {
arr[x++] = array[t][i];
}
if (++t > b) {
break;
}
for (int i = t;i <= b;i++) {
arr[x++] = array[i][r];
}
if (--r < l) {
break;
}
for (int i = r;i >= l;i--) {
arr[x++] = array[b][i];
}
if (--b < t) {
break;
}
for (int i = b;i >= t;i--) {
arr[x++] = array[i][l];
}
if (++l > r) {
break;
}
}
return arr;
}
}
以上便是对螺旋矩阵类型题的介绍了!!后续还会继续分享其它算法系列内容,如果这些内容对大家有帮助的话请给一个三连关注吧💕( •̀ ω •́ )✧( •̀ ω •́ )✧✨