Difficulty: Medium · LeetCode 200
Problem
Given an m x n 2D binary grid grid where '1' represents land and '0' water, return number of islands.
Understanding the problem
An island is surrounded by water and formed by connecting adjacent lands horizontally or vertically.
Intuition
Modify grid in-place (grid[r][c] = "0") to eliminate extra visited set storage.
Approach
Traverse every cell (r, c) in grid.
If cell is "1", increment island count and start DFS.
In DFS: set cell to "0" (sink island) and recurse 4 directions.
Naive Solution
DFS using explicit visited set.
class Solution:
def numIslands(self, grid):
rows = len(grid)
cols = len(grid[0])
visited = set()
def dfs(r, c):
if (
r < 0 or r >= rows or
c < 0 or c >= cols or
grid[r][c] == "0" or
(r, c) in visited
):
return
visited.add((r, c))
dfs(r + 1, c)
dfs(r - 1, c)
dfs(r, c + 1)
dfs(r, c - 1)
count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == "1" and (r, c) not in visited:
count += 1
dfs(r, c)
return countclass Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int rows = grid.size(), cols = grid[0].size();
vector<vector<bool>> visited(rows, vector<bool>(cols, false));
function<void(int, int)> dfs = [&](int r, int c) {
if (r < 0 || r >= rows || c < 0 || c >= cols ||
grid[r][c] == '0' || visited[r][c])
return;
visited[r][c] = true;
dfs(r + 1, c);
dfs(r - 1, c);
dfs(r, c + 1);
dfs(r, c - 1);
};
int count = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == '1' && !visited[r][c]) {
count++;
dfs(r, c);
}
}
}
return count;
}
};class Solution {
private char[][] grid;
private boolean[][] visited;
private int rows, cols;
public int numIslands(char[][] grid) {
this.grid = grid;
rows = grid.length;
cols = grid[0].length;
visited = new boolean[rows][cols];
int count = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == '1' && !visited[r][c]) {
count++;
dfs(r, c);
}
}
}
return count;
}
private void dfs(int r, int c) {
if (r < 0 || r >= rows || c < 0 || c >= cols ||
grid[r][c] == '0' || visited[r][c])
return;
visited[r][c] = true;
dfs(r + 1, c);
dfs(r - 1, c);
dfs(r, c + 1);
dfs(r, c - 1);
}
}var numIslands = function(grid) {
const rows = grid.length;
const cols = grid[0].length;
const visited = new Set();
const dfs = (r, c) => {
if (
r < 0 || r >= rows ||
c < 0 || c >= cols ||
grid[r][c] === "0" ||
visited.has(r * cols + c)
) return;
visited.add(r * cols + c);
dfs(r + 1, c);
dfs(r - 1, c);
dfs(r, c + 1);
dfs(r, c - 1);
};
let count = 0;
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (grid[r][c] === "1" && !visited.has(r * cols + c)) {
count++;
dfs(r, c);
}
}
}
return count;
};Time: O(R × C) · Aux Space: O(R × C)
Optimized Code (Python 3)
class Solution:
def numIslands(self, grid):
rows = len(grid)
cols = len(grid[0])
def dfs(r, c):
if (
r < 0 or r >= rows or
c < 0 or c >= cols or
grid[r][c] == "0"
):
return
grid[r][c] = "0"
dfs(r + 1, c)
dfs(r - 1, c)
dfs(r, c + 1)
dfs(r, c - 1)
count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == "1":
count += 1
dfs(r, c)
return countclass Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int rows = grid.size(), cols = grid[0].size();
function<void(int, int)> dfs = [&](int r, int c) {
if (r < 0 || r >= rows || c < 0 || c >= cols || grid[r][c] == '0')
return;
grid[r][c] = '0';
dfs(r + 1, c);
dfs(r - 1, c);
dfs(r, c + 1);
dfs(r, c - 1);
};
int count = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == '1') {
count++;
dfs(r, c);
}
}
}
return count;
}
};class Solution {
private char[][] grid;
private int rows, cols;
public int numIslands(char[][] grid) {
this.grid = grid;
rows = grid.length;
cols = grid[0].length;
int count = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == '1') {
count++;
dfs(r, c);
}
}
}
return count;
}
private void dfs(int r, int c) {
if (r < 0 || r >= rows || c < 0 || c >= cols || grid[r][c] == '0')
return;
grid[r][c] = '0';
dfs(r + 1, c);
dfs(r - 1, c);
dfs(r, c + 1);
dfs(r, c - 1);
}
}var numIslands = function(grid) {
const rows = grid.length;
const cols = grid[0].length;
const dfs = (r, c) => {
if (
r < 0 || r >= rows ||
c < 0 || c >= cols ||
grid[r][c] === "0"
) return;
grid[r][c] = "0";
dfs(r + 1, c);
dfs(r - 1, c);
dfs(r, c + 1);
dfs(r, c - 1);
};
let count = 0;
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (grid[r][c] === "1") {
count++;
dfs(r, c);
}
}
}
return count;
};Time: O(R × C) · Aux Space: O(R × C) recursion call stack · Extra Visited Space: O(1)