持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
大家好 我是丝瓜咸蛋汤。今天带来的是一道在LeetCode上的题目,题目难度为中等
。就在此为大家分享一下解答思路。
题目阐述
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
思路阐述
因为我们在遍历矩阵的时候,如果当前项等于 0,很容易将同一行的所有项设置为 0。但是,很难将同一列的项设置为 0。
还有,当我们遍历下一行时,如果遇到 0,如果它最初是非零或 0,我们如何识别该元素?
我的解决方案是设置一个名为“judge”的新矩阵进行判断,如下所示:
- 默认值为 0
- 当
matrix[i][j]==0
设置judge[i][j]=0
- 非零项被转换为0,因为在同一行或同一列中有一个零项,设置
judge[i][j]=-1
实现代码
实现代码如下:
/**
Do not return anything, modify matrix in-place instead.
*/
function setZeroes(matrix: number[][]): void {
let rlength = matrix.length
let clength = matrix[0].length
let judge=new Array(rlength)
for(let i=0;i<rlength;i++)
judge[i]=new Array(clength).fill(0)
for (let i = 0; i < rlength; i++) {
for (let j = 0; j < clength; j++) {
if (matrix[i][j] == 0 && judge[i][j] == 0) {
for (let n = 0; n < clength; n++) {
if (matrix[i][n] != 0) {
matrix[i][n] = 0
judge[i][n] = -1
}
}
for (let m = 0; m < rlength; m++) {
if (matrix[m][j] != 0 ) {
matrix[m][j] = 0
judge[m][j] = -1
}
}
}
}
}
};
坑点
在这里我创建二维数组judge
的时候,我是这样写的:
我在使用 Array.fill()
let judge=new Array(rlength).fill(new Array(clength).fill(0))
但是当我将一个非零元素转换为-1时,我发现所有元素都被改变了。
这是使用fill()方法创建二维数组的缺点。
其他解法
使用一个标记变量
我们可以对方法二进一步优化,只使用一个标记变量记录第一列是否原本存在 00。这样,第一列的第一个元素即可以标记第一行是否出现 00。但为了防止每一列的第一个元素被提前更新,我们需要从最后一行开始,倒序地处理矩阵元素。(via 官方)
var setZeroes = function(matrix) {
const m = matrix.length, n = matrix[0].length;
let flagCol0 = false;
for (let i = 0; i < m; i++) {
if (matrix[i][0] === 0) {
flagCol0 = true;
}
for (let j = 1; j < n; j++) {
if (matrix[i][j] === 0) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
for (let i = m - 1; i >= 0; i--) {
for (let j = 1; j < n; j++) {
if (matrix[i][0] === 0 || matrix[0][j] === 0) {
matrix[i][j] = 0;
}
}
if (flagCol0) {
matrix[i][0] = 0;
}
}
};
我是丝瓜咸蛋汤
一名热爱阿森纳的前端工程师
如果本文对您有帮助,可以给一个免费的赞吗?谢谢!