LeetCode Hot 100 (6) 矩阵
小帅 1/7/2024 LeetCode
# 73. 矩阵置零 (opens new window)
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 (opens new window) 算法。
示例 1:
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]
1
2
2
示例 2:
输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
1
2
2
提示:
- m == matrix.length
- n == matrix[0].length
- 1 <= m, n <= 200
- -2^31 <= matrix[i][j] <= 2^31 - 1
进阶:
- 一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
- 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
- 你能想出一个仅使用常量空间的解决方案吗?
思路:
用第一行和第一列的数是否为0来判断某行某列是否为0,用两个标志表示第一行和第一列是否需要全变为0。
代码:
C++代码
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
bool flagRow = false;
int m = matrix.size();
int n = matrix[0].size();
for(int i=0;i<n;i++) {
if(matrix[0][i]==0) {
flagRow = true;
}
}
bool flagCol = false;
for(int i=0;i<m;i++) {
if(matrix[i][0]==0) {
flagCol = 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++) {
if(matrix[i][0]==0) {
for(int j=1;j<n;j++) {
matrix[i][j] = 0;
}
}
}
for(int i=1;i<n;i++) {
if(matrix[0][i]==0) {
for(int j=1;j<m;j++) {
matrix[j][i] = 0;
}
}
}
if(flagRow) {
for(int i=0;i<n;i++) {
matrix[0][i] = 0;
}
}
if(flagCol) {
for(int i=0;i<m;i++) {
matrix[i][0] = 0;
}
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Go代码
func setZeroes(matrix [][]int) {
m := len(matrix)
n := len(matrix[0])
flagRow := false
for i:=0;i<n;i++ {
if matrix[0][i] == 0 {
flagRow = true
}
}
flagCol := false
for i:=0;i<m;i++ {
if matrix[i][0] == 0 {
flagCol = true
}
}
for i:=1;i<m;i++ {
for j:=1;j<n;j++ {
if matrix[i][j] == 0 {
matrix[i][0] = 0
matrix[0][j] = 0
}
}
}
for i:=1;i<m;i++ {
if matrix[i][0] == 0 {
for j:=1;j<n;j++ {
matrix[i][j] = 0
}
}
}
for i:=1;i<n;i++ {
if matrix[0][i] == 0 {
for j:=1;j<m;j++ {
matrix[j][i] = 0
}
}
}
if flagRow {
for i:=0;i<n;i++ {
matrix[0][i] = 0
}
}
if flagCol {
for i:=0;i<m;i++ {
matrix[i][0] = 0
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 54. 螺旋矩阵 (opens new window)
题目:
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
1
2
2
示例 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]
1
2
2
提示:
- m == matrix.length
- n == matrix[i].length
- 1 <= m, n <= 10
- -100 <= matrix[i][j] <= 100
思路:
模拟 用一个二维数组表示四种变化,当下一个坐标越界或者遍历过时需要转到下一种变化
代码:
C++代码
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int x = 0, y = 0;
vector<vector<int>> di = {{0,1},{1,0},{0,-1},{-1,0}};
int m = matrix.size();
int n = matrix[0].size();
vector<vector<int>> flag(m,vector<int>(n,-1));
int k = m*n;
int t = 0;
vector<int> res;
while(k--) {
res.push_back(matrix[x][y]);
flag[x][y] = 0;
int dx = x + di[t][0];
int dy = y + di[t][1];
if(dx<0||dx>=m||dy<0||dy>=n||flag[dx][dy]==0) {
t = (t+1)%4;
}
x = x + di[t][0];
y = y + di[t][1];
}
return res;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Go代码
func spiralOrder(matrix [][]int) []int {
m := len(matrix)
n := len(matrix[0])
di := [][]int{{0,1},{1,0},{0,-1},{-1,0}}
flag := make([][]int,m)
for i:=0;i<m;i++ {
flag[i] = make([]int,n)
}
x := 0
y := 0
t := 0
k := m*n
res := make([]int,0)
for k!=0 {
k--
res = append(res,matrix[x][y])
flag[x][y] = 1
dx := x + di[t][0]
dy := y + di[t][1]
if dx<0||dx>=m||dy<0||dy>=n||flag[dx][dy]==1 {
t = (t+1)%4
}
x = x + di[t][0]
y = y + di[t][1]
}
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 48. 旋转图像 (opens new window)
题目:
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在原地 (opens new window) 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]
1
2
2
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
1
2
2
提示:
- n == matrix.length == matrix[i].length
- 1 <= n <= 20
- -1000 <= matrix[i][j] <= 1000
思路:
先将上下的横排反转,然后按照左上右下的轴进行反转
代码:
C++代码
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
for(int i=0;i<m/2;i++) {
for(int j=0;j<n;j++) {
swap(matrix[i][j],matrix[n-1-i][j]);
}
}
for(int i=1;i<m;i++) {
for(int j=0;j<i;j++) {
swap(matrix[i][j],matrix[j][i]);
}
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Go代码
func rotate(matrix [][]int) {
m := len(matrix)
n := len(matrix[0])
for i:=0;i<m/2;i++ {
for j:=0;j<n;j++ {
matrix[i][j], matrix[n-1-i][j] = matrix[n-1-i][j], matrix[i][j]
}
}
for i:=1;i<m;i++ {
for j:=0;j<i;j++ {
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 240. 搜索二维矩阵 II (opens new window)
题目:
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例 1:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
1
2
2
示例 2:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false
1
2
2
提示:
- m == matrix.length
- n == matrix[i].length
- 1 <= n, m <= 300
- -10^9 <= matrix[i][j] <= 10^9
- 每行的所有元素从左到右升序排列
- 每列的所有元素从上到下升序排列
- -10^9 <= target <= 10^9
思路:
从右上角开始搜索,如果当前值比目标值大则往左侧搜索(因为当前列下面的更大),否则忘下侧搜索(当前行左侧更小)
代码:
C++代码
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size();
int n = matrix[0].size();
int x = 0, y = n-1;
while(true) {
if (x>=m||y<0) {
return false;
}
if(matrix[x][y]==target) {
return true;
} else if(matrix[x][y]>target) {
y--;
} else {
x++;
}
}
return false;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Go代码
func searchMatrix(matrix [][]int, target int) bool {
m := len(matrix)
n := len(matrix[0])
x := 0
y := n-1
for true {
if x==m||y==-1 {
return false
}
if matrix[x][y]==target {
return true
} else if matrix[x][y]>target {
y--
} else {
x++
}
}
return false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19