You are given a matrix grid where grid[i] is either a 0 (representing water) or 1 (representing land).
An island is defined as a group of 1's connected horizontally or vertically. You may assume all four edges of the grid are surrounded by water.
The area of an island is defined as the number of cells within the island.
Return the maximum area of an island in grid. If no island exists, return 0.
Example 1:
Input: grid = [
[0,1,1,0,1],
[1,0,1,0,1],
[0,1,1,0,1],
[0,1,0,0,1]
]
Output: 6Explanation: 1's cannot be connected diagonally, so the maximum area of the island is 6.
Constraints:
1 <= grid.length, grid[i].length <= 50
You should aim for a solution with O(m * n) time and O(m * n) space, where m is the number of rows and n is the number of columns in the grid.
An island is a group of 1's in which every 1 is reachable from any other 1 in that group. Can you think of an algorithm that can find the number of groups by visiting a group only once? Maybe there is a recursive way of doing it.
We can use the Depth First Search (DFS) algorithm to traverse each group by starting at a cell with 1 and recursively visiting all the cells that are reachable from that cell and are also 1. Can you think about how to find the area of that island? How would you implement this?
We traverse the grid, and when we encounter a 1, we initialize a variable area. We then start a DFS from that cell to visit all connected 1's recursively, marking them as 0 to indicate they are visited. At each recursion step, we increment area. After completing the DFS, we update maxArea, which tracks the maximum area of an island in the grid, if maxArea < area. Finally, after traversing the grid, we return maxArea.
Before attempting this problem, you should be comfortable with:
An island is a group of connected 1s.
To find the maximum area, we explore each island fully and count how many cells it contains.
Depth First Search (dfs) helps us:
We mark cells as visited so we don't count the same cell twice.
1) and not visited, run dfs from it.dfs:0), or already visited.1 + area from all 4 neighbors.dfs call, update the maximum area.class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ROWS, COLS = len(grid), len(grid[0])
visit = 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 visit
):
return 0
visit.add((r, c))
return (1 + dfs(r + 1, c) +
dfs(r - 1, c) +
dfs(r, c + 1) +
dfs(r, c - 1))
area = 0
for r in range(ROWS):
for c in range(COLS):
area = max(area, dfs(r, c))
return areaWhere is the number of rows and is the number of columns in the .
An island is a group of connected 1s.
To find the maximum area, we explore each island completely and count how many cells it has.
Using Breadth First Search (bfs):
1)0 to avoid revisiting1) is found:bfs from that cell.0.1.bfs:1), add it to the queue, mark it 0, and increase area.bfs completes, update the maximum area.class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
ROWS, COLS = len(grid), len(grid[0])
area = 0
def bfs(r, c):
q = deque()
grid[r][c] = 0
q.append((r, c))
res = 1
while q:
row, col = q.popleft()
for dr, dc in directions:
nr, nc = dr + row, dc + col
if (nr < 0 or nc < 0 or nr >= ROWS or
nc >= COLS or grid[nr][nc] == 0
):
continue
q.append((nr, nc))
grid[nr][nc] = 0
res += 1
return res
for r in range(ROWS):
for c in range(COLS):
if grid[r][c] == 1:
area = max(area, bfs(r, c))
return areaWhere is the number of rows and is the number of columns in the .
Think of each land cell (1) as a node in a graph.
If two land cells are adjacent (up, down, left, right), they belong to the same island.
Using Disjoint Set Union (Union-Find):
This approach is useful when you want to group connected components efficiently.
index = r * COLS + c.ROWS * COLS elements.1):4 neighbors.class DSU:
def __init__(self, n):
self.Parent = list(range(n + 1))
self.Size = [1] * (n + 1)
def find(self, node):
if self.Parent[node] != node:
self.Parent[node] = self.find(self.Parent[node])
return self.Parent[node]
def union(self, u, v):
pu = self.find(u)
pv = self.find(v)
if pu == pv:
return False
if self.Size[pu] >= self.Size[pv]:
self.Size[pu] += self.Size[pv]
self.Parent[pv] = pu
else:
self.Size[pv] += self.Size[pu]
self.Parent[pu] = pv
return True
def getSize(self, node):
par = self.find(node)
return self.Size[par]
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ROWS, COLS = len(grid), len(grid[0])
dsu = DSU(ROWS * COLS)
def index(r, c):
return r * COLS + c
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
area = 0
for r in range(ROWS):
for c in range(COLS):
if grid[r][c] == 1:
for dr, dc in directions:
nr, nc = r + dr, c + dc
if (nr < 0 or nc < 0 or nr >= ROWS or
nc >= COLS or grid[nr][nc] == 0
):
continue
dsu.union(index(r, c), index(nr, nc))
area = max(area, dsu.getSize(index(r, c)))
return areaWhere is the number of rows and is the number of columns in the .
A common mistake is not marking cells as visited before or immediately after processing them. This leads to infinite recursion in DFS or infinite loops in BFS, as the same cell gets added to the queue or call stack repeatedly. Always mark a cell as visited (either by using a separate visited set or by modifying the grid value to 0) before exploring its neighbors.
Failing to properly check grid boundaries before accessing grid[r][c] causes index-out-of-bounds errors. The order of conditions matters: always check r >= 0 && r < ROWS && c >= 0 && c < COLS before checking grid[r][c]. Short-circuit evaluation prevents the array access when indices are invalid.
In BFS, a subtle bug occurs when you increment the area count at the wrong time. The area should be incremented when a cell is added to the queue and marked as visited, not when it is dequeued. If you increment when dequeuing, you may count the same cell multiple times if it gets added to the queue from different neighbors before being processed.