携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
给定一个 m * n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
示例
// 示例1
1 1 1 1 0 1
1 0 1 => 0 0 0
1 1 1 1 0 1
// 示例2
0 1 2 0 0 0 0 0
3 4 5 2 => 0 4 5 0
1 3 1 5 0 3 1 0
思路
对于二维数组,我们可以考虑使用双重循环来遍历数组的每一项
-
遍历二维数组
-
当前遍历项为数字
0时,将其横竖两个方向不为0的数字变为字母o-
为什么要先改为字母
o,拿示例2来说,如果直接改为数字0,那么第一轮遍历会将数组变为:0 0 0 0 0 4 5 2 0 3 1 5第二轮的结果为:
0 0 0 0 0 0 0 0 0 3 1 5则最终结果肯定是一个全为
0的数组
-
-
最后将字母
o改为数字0即可
代码实现
var setZero = function(matrix) {
let n = matrix.length; // 获取总行数
let m = matrix[0].length; // 获取总行数
// 开始遍历二维数组
for(let i=0; i<n; i++) { // 行遍历
for(let j=0; j<m; j++) { // 列遍历
if(matrix[i][j] === 0) { // 发现当前遍历项为 0 了
for(let z=0; z<n; z++) { // 处理当前行的所有数据
if(matrix[z][j] !== 0) { // 避免影响到其他 “原始的数字0”
matrix[z][j] = "o";
}
}
for(let z=0; z<m; z++) { // 处理当前列的所有数据
if(matrix[i][z] !== 0) {
matrix[i][z] = "0";
}
}
}
}
}
// 将全部的字母 o 替换成数字 0
for(let i=0; i<n; i++) {
for(let j=0; j<m; j++) {
matrix[i][j] = 0;
}
}
return matrix;
}
优化(标记法):只维护两个一维数组,分别代表行列
var setZeroes = function(matrix) {
const n = matrix.length, m = matrix[0].length;
// 创建行列数组,内部元素全部初始化为false,表示此行/列不为0
const row = new Array(n).fill(false);
const col = new Array(m).fill(false);
// 遍历二维数组
for(let i=0; i<n; i++) {
for(let j=0; j<m; j++) {
if(matrix[i][j] === 0) {
// 例如示例1中 [1,1] 是0,则这里就是 row[1] = col[1] = true
// 代表第一行全是0,第一列也全是0
row[i] = col[j] = true;
}
}
}
// 依据row和col两个数组,更新0
for(let i=0; i<n; i++) {
for(let j=0; j<m; j++) {
if(row[i] || col[j]) matrix[i][j] = 0;
}
}
return matrix;
}