二维数组的花式遍历技巧
基于labuladong的算法网站,二维数组的花式遍历技巧
1、顺/逆时针旋转矩阵
力扣第48题,旋转图像;
操作步骤:
- 将矩阵按照左上到右下的对角线进行镜像对称;
- 再对矩阵的每一行进行反转;
- 结果即为顺时针旋转90度的结果;
(1)顺时针旋转矩阵
[48]旋转图像
class Solution {
public void rotate(int[][] matrix) {
reverse(matrix);
rowReverse(matrix);
}
// 将矩阵从左上到右下进行翻转
void reverse(int[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
for (int j = i + 1; j < matrix.length; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
// 将矩阵的每一行所有元素进行翻转
void rowReverse(int[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
int left = 0, right = matrix.length - 1;
while (left < right) {
int temp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = temp;
left++;
right--;
}
}
}
}
重点:
- 难点在于将row变成column,将column变成row;
- 只有按照对角线这个样子操作才可以完成上述要求;
(2)逆时针旋转矩阵
如何将矩阵逆时针旋转90°呢?
- 将矩阵按照从右上到左下对称翻转矩阵;
- 再逐行翻转矩阵即可得到;
class Solution {
// 逆时针旋转
public void rotate(int[][] matrix) {
reverse(matrix);
rowReverse(matrix);
}
// 将矩阵从右上到左下进行翻转
void reverse(int[][] matrix) {
for (int i = 0; i < matrix.length - 1; i++) {
for (int j = 0; j < matrix.length - 1 - i; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[matrix.length - 1 - j][matrix.length - 1 - i];
matrix[matrix.length - 1 - j][matrix.length - 1 - i] = temp;
}
}
}
// 将矩阵的每一行所有元素进行翻转
void rowReverse(int[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
int left = 0, right = matrix.length - 1;
while (left < right) {
int temp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = temp;
left++;
right--;
}
}
}
}
2、矩阵的螺旋遍历
(1)螺旋矩阵
力扣第54题,螺旋矩阵
解题的核心思路是:
- 使用四个变量确定为遍历元素的边界;
- 随着螺旋遍历,缩紧四个边界,直到螺旋遍历完整个数组;
[54]螺旋矩阵
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
// 四个指针
int upper = 0, left = 0;
int low = m - 1, right = n - 1;
// 返回的结果
List<Integer> result = new LinkedList<>();
while (result.size() < m * n) {
// 左到右
if (upper <= low) {
for (int i = left; i <= right; i++) {
result.add(matrix[upper][i]);
}
upper++;
}
// 上到下
if (left <= right) {
for (int i = upper; i <= low; i++) {
result.add(matrix[i][right]);
}
right--;
}
// 右到左
if (upper <= low) {
for (int i = right; i >= left; i--) {
result.add(matrix[low][i]);
}
low--;
}
// 下到上
if (left <= right) {
for (int i = low; i >= upper; i--) {
result.add(matrix[i][left]);
}
left++;
}
}
return result;
}
}
(2)螺旋矩阵Ⅱ
力扣第59题,螺旋矩阵Ⅱ
[59]螺旋矩阵 II
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int left = 0, upper = 0;
int low = n - 1, right = n - 1;
int count = 0;
while (count < n * n) {
// 左到右
if (upper <= low) {
for (int i = left; i <= right; i++) {
res[upper][i] = ++count;
}
upper++;
}
// 上到下
if (left <= right) {
for (int i = upper; i <= low; i++) {
res[i][right] = ++count;
}
right--;
}
// 右到左
if (upper <= low) {
for (int i = right; i >= left; i--) {
res[low][i] = ++count;
}
low--;
}
// 下到上
if (left <= right) {
for (int i = low; i >= upper; i--) {
res[i][left] = ++count;
}
left++;
}
}
return res;
}
}