从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结
73. 矩阵置零
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
示例 1:
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]
示例 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]]
提示:
m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
−
2
3
1
-2^31
−231 <= matrix[i][j] <=
2
3
1
−
1
2^31 - 1
231−1
进阶:
一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个仅使用常量空间的解决方案吗?
方法一
思路:用两个set分别记录需要置0的行和需要置0的列。第一次遍历矩阵时,若发现一个元素为0,则将其行和列值分别加入到两个set中。第二次遍历矩阵时,将行set中的行全部置0,将列set中的列全部置0。
public void setZeroes(int[][] matrix) {
if(matrix == null || matrix.length == 0)
return;
int m = matrix.length, n = matrix[0].length;
Set<Integer> row = new HashSet<Integer>();
Set<Integer> col = new HashSet<Integer>();
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(matrix[i][j] == 0){
row.add(i);
col.add(j);
}
}
}
for(int i : row){
for(int j = 0; j < n; j++)
matrix[i][j] = 0;
}
for(int j : col){
for(int i = 0; i < m; i++)
matrix[i][j] = 0;
}
}
时间复杂度:O(m×n)
空间复杂度:O(m+n) 最坏情况是矩阵中全部元素为0的情况,这时两个set的大小分别为m和n。
方法二
思路:不用额外空间,让首行和首列记录某列和某行是否有0
算法步骤:
首先用两个布尔类型变量firstRow和firstCol分别记录矩阵的首行和首列中是否有0
遍历除首行和首列外的所有元素,若元素matrix[i][j]为0,则将它对应的首行和首列中的元素matrix[i][0]和matrix[0][j]置为0,意为此行和列后续需要被置0(由于修改后首行和首列是否有0的信息会被破坏掉,因此需要有之前的步骤一)
遍历首行和首列,若发现首行中有元素为0,则将此元素所处的列全部置0,若发现首列中有元素为0,则将此元素所处的行全部置0。
根据步骤一的布尔类型变量firstRow和firstCol来判断首行和首列是否需要被置0。
public void setZeroes(int[][] matrix) {
if(matrix == null || matrix.length == 0)
return;
int m = matrix.length, n = matrix[0].length;
boolean firstRow = false, firstCol = false;
//步骤一
for(int i = 0; i < m; i++){
if(matrix[i][0] == 0)
firstCol = true;
}
for(int j = 0; j < n; j++){
if(matrix[0][j] == 0)
firstRow = 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 = 0; j < n; j++)
matrix[i][j] = 0;
}
}
for(int j = 1; j < n; j++){
if(matrix[0][j] == 0){
for(int i = 0; i < m; i++)
matrix[i][j] = 0;
}
}
//步骤四
if(firstRow){
for(int j = 0; j < n; j++)
matrix[0][j] = 0;
}
if(firstCol){
for(int i = 0; i < m; i++)
matrix[i][0] = 0;
}
}
时间复杂度:O(m×n)
空间复杂度:O(1)