Max Area of Island
DFS each unvisited land cell; flood-fill, count cells, track the maximum.
4 min read
dfs grid flood-fill
Problem#
Given a binary grid, return the maximum area of any island (connected group of 1s by 4-direction adjacency). Return 0 if none.
Examples#
[[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],...]→6[[0,0,0,0,0,0,0,0]]→0
Constraints#
m == grid.length,n == grid[i].length,1 <= m, n <= 50.
Approach#
Scan each cell. On finding grid[i][j] == 1, run a DFS that flips visited cells to 0 and counts them.
Solution#
class Solution {public: int maxAreaOfIsland(vector<vector<int>>& grid) { int m = grid.size(), n = grid[0].size(), best = 0; function<int(int,int)> dfs = [&](int r, int c) -> int { if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == 0) return 0; grid[r][c] = 0; return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1); }; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) if (grid[i][j] == 1) best = max(best, dfs(i, j)); return best; }};func maxAreaOfIsland(grid [][]int) int { m, n := len(grid), len(grid[0]) best := 0 var dfs func(r, c int) int dfs = func(r, c int) int { if r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == 0 { return 0 } grid[r][c] = 0 return 1 + dfs(r+1, c) + dfs(r-1, c) + dfs(r, c+1) + dfs(r, c-1) } for i := 0; i < m; i++ { for j := 0; j < n; j++ { if grid[i][j] == 1 { if a := dfs(i, j); a > best { best = a } } } } return best}from typing import List
class Solution: def maxAreaOfIsland(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0])
def dfs(r: int, c: int) -> int: if r < 0 or r >= m or c < 0 or c >= n or grid[r][c] == 0: return 0 grid[r][c] = 0 return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1)
best = 0 for i in range(m): for j in range(n): if grid[i][j] == 1: best = max(best, dfs(i, j)) return bestfunction maxAreaOfIsland(grid) { const m = grid.length, n = grid[0].length; let best = 0; const dfs = (r, c) => { if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] === 0) return 0; grid[r][c] = 0; return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1); }; for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (grid[i][j] === 1) best = Math.max(best, dfs(i, j)); } } return best;}class Solution { private int[][] grid; private int m, n;
public int maxAreaOfIsland(int[][] grid) { this.grid = grid; m = grid.length; n = grid[0].length; int best = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) best = Math.max(best, dfs(i, j)); } } return best; }
private int dfs(int r, int c) { if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == 0) return 0; grid[r][c] = 0; return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1); }}function maxAreaOfIsland(grid: number[][]): number { const m = grid.length, n = grid[0].length; let best = 0; const dfs = (r: number, c: number): number => { if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] === 0) return 0; grid[r][c] = 0; return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1); }; for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (grid[i][j] === 1) best = Math.max(best, dfs(i, j)); } } return best;}Editorial#
Marking visited by mutating to 0 saves on a separate visited matrix. Each cell is visited at most once, so the overall sweep is O(m*n). Recursion depth is bounded by the largest island area.
Complexity#
- Time: O(m*n).
- Space: O(m*n) recursion in the worst case.
Concept revision#
Related#