Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
给定一个 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]]
进阶:
一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。 你能想出一个仅使用常量空间的解决方案吗?
二、解题思路
看到这道题感觉没有怎么碰到过同类型的题目,如这道题所说,使用一个矩阵来记录是否要置为0就可以得到O(mn) 的空间复杂度解法。相应地,可以使用两个数组,分别表示哪些行和哪些列需要置0,即为O(m+n) 的空间复杂度解法。下面的AC代码也是按这种思路写的,没直接想到常量空间解法。
三、AC代码
var setZeroes = function(matrix) {
let m = new Map();
let n = new Map();
for (let i in matrix){
for(let j in matrix[0]){
if(matrix[i][j] === 0){
m.set(i,true);
n.set(j,true);
}
}
}
m.forEach((val,row) =>{
for(let column in matrix[row]) {
matrix[row][column] = 0;
}
})
n.forEach((val,column) =>{
for (let row in matrix){
matrix[row][column] = 0;
}
})
return matrix;
};
四、总结
贴一个常量空间解法,实际上使用了把第一行和第一列取代AC代码中的Map的trick
public void setZeroes(int[][] matrix) {
//标记第一行是否有数字0
boolean row = false;
//标记第一列是否有数字0
boolean col = false;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] == 0) {
//如果第一行或者第一列本来就有0,就把他标记一
//下,最后再把第一行或者第一列全部置为0
if (i == 0)
row = true;
if (j == 0)
col = true;
//把最上面一行和最左边一列对应的位置标注为0
matrix[0][j] = matrix[i][0] = 0;
}
}
}
//把那些应该为0的行和列全部置为0
for (int i = 1; i < matrix.length; i++) {
for (int j = 1; j < matrix[0].length; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
}
}
//如果第一列本来就有0,把第一列全部变为0
if (col) {
for (int i = 0; i < matrix.length; i++)
matrix[i][0] = 0;
}
//如果第一行本来就有0,把第一行全部变为0
if (row) {
for (int j = 0; j < matrix[0].length; j++)
matrix[0][j] = 0;
}
}
作者:数据结构和算法
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvmy42/?discussion=gEzDPZ