Number of Islands
// Boundary check const isOffBoundary = (grid, r, c) => { return r < 0 || c < 0 || r >= grid.length || c >= grid[0].length; }; // Iterative DFS var numIslands = function (grid) { if (!grid.length || !grid[0].length) { return 0; } const Dir = [ [1, 0], [-1, 0], [0, 1], [0, -1], ]; const rowsLen = grid.length; const colsLen = grid[0].length; let count = 0; for (let r = 0; r < rowsLen; r++) { for (let c = 0; c < colsLen; c++) { if (grid[r][c] === "1") { count++; const stack = [[r, c]]; while (stack.length > 0) { const coord = stack.pop(); grid[coord[0]][coord[1]] = "0"; for (const [dr, dc] of Dir) { const nr = coord[0] + dr; const nc = coord[1] + dc; if (isOffBoundary(grid, nr, nc) || grid[nr][nc] === "0") { continue; } stack.push([nr, nc]); } } } } } return count; };
// Boundary check const isOffBoundary = (grid, r, c) => { return r < 0 || c < 0 || r >= grid.length || c >= grid[0].length; }; // Recursive DFS var numIslands = function (grid) { if (!grid.length || !grid[0].length) { return 0; } const rowsLen = grid.length; const colsLen = grid[0].length; let count = 0; for (let r = 0; r < rowsLen; r++) { for (let c = 0; c < colsLen; c++) { if (grid[r][c] === "1") { count++; explore(grid, r, c); } } } return count; }; const explore = (grid, r, c) => { if (isOffBoundary(grid, r, c) || grid[r][c] === "0") { return; } grid[r][c] = "0"; explore(grid, r + 1, c); explore(grid, r - 1, c); explore(grid, r, c + 1); explore(grid, r, c - 1); };
// Union Find class DSU { constructor(LEN) { this.sets = [...Array(LEN).keys()]; } find(x) { if (this.sets[x] !== x) { return (this.sets[x] = this.find(this.sets[x])); } return x; } union(x, y) { if (this.sets[x] === this.sets[y]) { return; } x = this.find(x); y = this.find(y); this.sets[x] = y; } findComponents() { let count = 0; for (let i = 0; i < this.sets.length; i++) { if (this.sets[i] === i) { count++; } } return count; } markInvalid(x) { this.sets[x] = -1; } } var numIslands = function (grid) { if (!grid || !grid.length) return 0; const DIRS = [ [1, 0], [0, 1], ]; // only 2 direction - bottom and right const ROWS = grid.length; const COLS = grid[0].length; const dsu = new DSU(ROWS * COLS); const isValid = (r, c) => r >= 0 && r < ROWS && c >= 0 && c < COLS && grid[r][c] === "1"; const normalize = (r, c) => r * COLS + c; for (let r = 0; r < ROWS; r++) { for (let c = 0; c < COLS; c++) { if (grid[r][c] === "1") { for (let [dr, dc] of DIRS) { let nr = r + dr; let nc = c + dc; if (!isValid(nr, nc)) { continue; } dsu.union(normalize(r, c), normalize(nr, nc)); } } else { dsu.markInvalid(normalize(r, c)); } } } return dsu.findComponents(); };
Union Find Tip:
Normalise MxN matrix's coordinates. (r * COLS) + c