I built the Set Matrix Zeroes algorithm in JavaScript. I have a lot of loops in my code, so was wondering if there is a better way to implement this algorithm.
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.
I loop through the matrix and when I find a 0, I set its entire row and column to a flag ('X'). I do not set 'X' if the position is a 0 because I might need to check this position in the future. At the end I replace all the 'X' to 0.
var setZeroes = function(matrix) {
if(matrix === null || matrix.length === 0)
return [];
for(let i=0; i<matrix.length; i++){
for(let j=0; j<matrix[i].length; j++){
if(matrix[i][j] === 0){
setFlag(matrix, i, j);
}
}
}
for(i=0; i<matrix.length; i++){
for(j=0; j<matrix[i].length; j++){
if(matrix[i][j] === 'X')
matrix[i][j] = 0;
}
}
};
const setFlag = function(matrix, i, j) {
matrix[i][j] = 'X';
let tempI = i+1;
while(tempI < matrix.length){
if(matrix[tempI][j] !== 0)
matrix[tempI][j] = 'X';
tempI++;
}
tempI = i-1;
while(tempI >= 0){
if(matrix[tempI][j] !== 0)
matrix[tempI][j] = 'X';
tempI--;
}
let tempJ = j+1;
while(tempJ < matrix[i].length){
if(matrix[i][tempJ] !== 0)
matrix[i][tempJ] = 'X';
tempJ++;
}
tempJ = j-1;
while(tempJ >= 0){
if(matrix[i][tempJ] !== 0)
matrix[i][tempJ] = 'X';
tempJ--;
}
}
```
1 Answer 1
From a short review;
- You probably want to encapsulate
if(matrix === null || matrix.length === 0)
into anisValidMatrix
function for re-use - I would drop the whole
i
/j
thing and go for variables named afterrow
andcol
- I would collect all the rows and columns with a 0 in one set of loops, and then clear the matrix based on the collected rows and columns in another set of loops.
let
only declares in the block, so thefor(i=0; i<matrix.length; i++){
creates a globali
- I much prefer
function setFlag(matrix, i, j) {
overconst setFlag = function(matrix, i, j) {
This is my current proposal, I did not test it, but you should get the gist of it;
//This does not catch everything, but it'll do
function isValidMatrix(matrix){
return !(!matrix || !matrix.length);
}
function setZeroes(matrix) {
if(!isValidMatrix(matrix))
return [];
const rows = [], cols = [];
for(let row = 0; row < matrix.length; row++){
for(let col = 0; col < matrix[row].length; col++){
if(matrix[row][col] === 0){
rows.push(row);
cols.push(col);
}
}
}
for(let row = 0; row < matrix.length; row++){
for(let col = 0; col < matrix[row].length; col++){
if(rows.includes(row) || cols.includes(col)){
matrix[row][col] = 0;
}
}
}
}
For further refinement, rows
and cols
might/will get multiple times the same value, so to deal with that gracefully you should use Sets for that.