矩阵操作
问题
Java 中矩阵相关的常见算法题有哪些?
答案
螺旋矩阵(LeetCode 54)
边界收缩法
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int j = left; j <= right; j++) result.add(matrix[top][j]); // →
top++;
for (int i = top; i <= bottom; i++) result.add(matrix[i][right]); // ↓
right--;
if (top <= bottom) {
for (int j = right; j >= left; j--) result.add(matrix[bottom][j]); // ←
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) result.add(matrix[i][left]); // ↑
left++;
}
}
return result;
}
搜索二维矩阵 II(LeetCode 240)
从右上角出发,类似 BST 搜索
public boolean searchMatrix(int[][] matrix, int target) {
int row = 0, col = matrix[0].length - 1;
while (row < matrix.length && col >= 0) {
if (matrix[row][col] == target) return true;
else if (matrix[row][col] > target) col--; // 太大,左移
else row++; // 太小,下移
}
return false;
}
// 时间 O(m + n)
旋转图像(LeetCode 48)
先转置,再水平翻转
public void rotate(int[][] matrix) {
int n = matrix.length;
// 1. 沿主对角线转置
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}
// 2. 每行左右翻转
for (int i = 0; i < n; i++) {
for (int j = 0; j < n / 2; j++) {
int tmp = matrix[i][j];
matrix[i][j] = matrix[i][n - 1 - j];
matrix[i][n - 1 - j] = tmp;
}
}
}
矩阵置零(LeetCode 73)
用第一行第一列作标记,O(1) 空间
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean firstRowZero = false, firstColZero = false;
// 检查第一行第一列是否有 0
for (int j = 0; j < n; j++) if (matrix[0][j] == 0) firstRowZero = true;
for (int i = 0; i < m; i++) if (matrix[i][0] == 0) firstColZero = true;
// 用第一行第一列做标记
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
// 根据标记置零
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
if (matrix[i][0] == 0 || matrix[0][j] == 0) matrix[i][j] = 0;
if (firstRowZero) for (int j = 0; j < n; j++) matrix[0][j] = 0;
if (firstColZero) for (int i = 0; i < m; i++) matrix[i][0] = 0;
}
常见面试问题
Q1: 矩阵题目的常见技巧?
答案:
| 技巧 | 典型题 |
|---|---|
| 边界收缩 | 螺旋矩阵 |
| 右上角搜索 | 搜索二维矩阵 |
| 转置 + 翻转 | 旋转图像 |
| 标记法 | 矩阵置零 |
| DFS/BFS | 岛屿数量 |
Q2: 如何用 空间对矩阵做操作?
答案:
利用矩阵自身空间作为标记(如第一行第一列),避免额外开辟数组。