【LeetCode 面试经典150题】4-矩阵
1 矩阵的基础
感觉矩阵的题很简单。迅速过完
12.23 一刷
1.1 表示矩阵
在Java中,矩阵通常可以用二维数组(int[][]、double[][]等)来表示。每个内部数组代表矩阵的一行。
1 | int[][] matrix = { |
1.2 创建矩阵
创建矩阵可以通过直接声明和初始化,或者使用循环动态创建。
1 | int rows = 3; |
相关题目
36.有效的数独 (看题解做出来,需要复习)
54.螺旋矩阵(做了一次没做对,需要复习)
48.旋转图像(一遍过)
73.矩阵置零 (一遍过)
289.生命游戏 (一遍过)
2 36.有效的数独 (需要复习)
中等
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
- 数字
1-9在每一行只能出现一次。 - 数字
1-9在每一列只能出现一次。 - 数字
1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图)
注意:
- 一个有效的数独(部分已被填充)不一定是可解的。
- 只需要根据以上规则,验证已经填入的数字是否有效即可。
- 空白格用
'.'表示。
示例 1:

1 | 输入:board = |
示例 2:
1 | 输入:board = |
提示:
board.length == 9board[i].length == 9board[i][j]是一位数字(1-9)或者'.'
分析
题目不难。做的时候没想到的是
- 没有想到如何判断3*3宫格。(可以用两个坐标来表示9个3*3宫格)
- 用数组代替hash表存储该行/该列/该3*3宫格是否出现该数字
1 | 不用完成数独,但是需要判断给出的数独是否是合法数独。核心思想如下: |
代码
1 | class Solution { |
3 54.螺旋矩阵(需要复习)
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:

1 | 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] |
示例 2:

1 | 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] |
提示:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 10-100 <= matrix[i][j] <= 100
分析
之前做过很多次。但是再做仍然会出现问题。具体是一些细节上的问题。
这次做能够知道3,4需要判断当前行是否遍历过,当前列是否遍历过
但是没有注意到的点为
举个例子,往右的时候需要初始化当前列,即
j=left。就是在往一个方向遍历移动的时候,需要初始化最开始移动的那个下标。第一次做的时候,里面的移动用的是for循环,而不是while,所以使用while来遍历的话,就需要在遍历的一开始指定j
1
2
3
4
5
6
7 j = left;
while(j<right){
res.add(matrix[top][j]);
j++;
num++;
}
top++;
1 | 模拟。 |
代码
1 | class Solution { |
4 48.旋转图像
中等
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在** 原地** 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:

1 | 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] |
示例 2:

1 | 输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] |
提示:
n == matrix.length == matrix[i].length1 <= n <= 20-1000 <= matrix[i][j] <= 1000
思路
没什么好说的,一遍过。
做过之后就是挺简单的题目
1 | 容易证明 |
代码
1 | class Solution { |
5 73.矩阵置零 (一遍过)
中等
给定一个 *m* x *n* 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
示例 1:

1 | 输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] |
示例 2:

1 | 输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]] |
提示:
m == matrix.lengthn == matrix[0].length1 <= m, n <= 200-231 <= matrix[i][j] <= 231 - 1
进阶:
- 一个直观的解决方案是使用
O(*m**n*)的额外空间,但这并不是一个好的解决方案。 - 一个简单的改进方案是使用
O(*m* + *n*)的额外空间,但这仍然不是最好的解决方案。 - 你能想出一个仅使用常量空间的解决方案吗?
5.1 思路
用了标记数组。
1 | 两个数组标记 |
5.2 代码
1 | class Solution { |
6 289.生命游戏 (一遍过)
中等
根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
- 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
- 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
- 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
- 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是 同时 发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。
给定当前 board 的状态,更新 board 到下一个状态。
注意 你不需要返回任何东西。
示例 1:

1 | 输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]] |
示例 2:

1 | 输入:board = [[1,1],[1,0]] |
提示:
m == board.lengthn == board[i].length1 <= m, n <= 25board[i][j]为0或1
进阶:
- 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
- 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
分析
之前做过有印象。
只要能明白下面的东西就好做了。
活->死 的细胞,用-1表示 死->活 的细胞,用-2表示
1 | 总结一下规则 |
代码
1 | class Solution { |