Description
Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.
An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Constraints
m == grid.lengthn == grid[i].length1 <= m, n <= 300grid[i][j]is'0'or'1'.
Examples
- Example 1:
Input:grid = [Output: 1
["1", "1", "1", "1", "0"],
["1", "1", "0", "1", "0"],
["1", "1", "0", "0", "0"],
["0", "0", "0", "0", "0"]
] - Example 2:
Input:grid = [Output:
["1", "1", "0", "0", "0"],
["1", "1", "0", "0", "0"],
["0", "0", "1", "0", "0"],
["0", "0", "0", "1", "1"]
]3
Solution 1: Depth-First Search (DFS)
Thought
We can use the DFS technique to traverse the entire grid. Whenever we encounter land, we can mark all other connected lands (if the question doesn’t allow changing the initial grid, you can use a hash set to keep track) and continue to count how many independent islands have been traversed in total.
Steps
- Use the DFS technique to traverse each element in the
grid. If the current element is'1', incrementnum_islandsby 1, and then calldfs_helperwith the current coordinates as input parameters. - In the
dfs_helperfunction:- Base Case: If the current coordinates are out of the
grid‘s range or the current element is not'1', terminate the current call. - If not, mark the current element as
'#'to indicate that it has been visited. - Recursively call
dfs_helperwith the four coordinates adjacent to the current position as parameters.
- Base Case: If the current coordinates are out of the
- After the traversal is complete, return the
num_islands.
Codes
def num_islands(grid: List[List[str]]) -> int:
m = len(grid)
n = len(grid[0])
num_islands = 0
def dfs_helper(i: int, j: int) -> None:
if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] != '1':
return
grid[i][j] = '#'
dfs_helper(i + 1, j)
dfs_helper(i - 1, j)
dfs_helper(i, j + 1)
dfs_helper(i, j - 1)
for i in range(m):
for j in range(n):
if grid[i][j] == '1':
num_islands += 1
dfs_helper(i, j)
return num_islandsPythonComplexities
- Time Complexity:
O(MN), whereNis the width of the grid andMis the length of the grid. - Space Complexity:
O(MN), whereNis the width of the grid andMis the length of the grid.
Solution 2: Breadth-First Search (BFS)
Thought
Similar to the DFS approach described above, we can also use BFS to traverse the entire grid. The only difference is that we don’t need to define a recursive helper function to extend to all other connected lands with the current land. Instead, we use a queue to expand outward. Using a queue for BFS search is a classic technique.
Steps
- Using the BFS technique to traverse each element in the
grid:- If the current element is not
'1', skip the current iteration. - If not, increment
num_islandsby 1, and then push the current coordinates(i, j)to thequeueas the initial starting point. - While the
queueis not empty, continue to pop out coordinates from the front of thequeue. If the popped coordinates are within thegrid‘s range and the corresponding element is'1', mark it as'#'and push the four adjacent coordinates at the end of thequeuein order.
- If the current element is not
- After the traversal is complete, return the
num_islands.
Codes
def num_islands(grid: List[List[str]]) -> int:
m = len(grid)
n = len(grid[0])
num_islands = 0
for i in range(m):
for j in range(n):
if grid[i][j] != '1':
continue
num_islands += 1
queue = [(i, j)]
while queue:
(x, y) = queue.pop()
if 0 <= x < m and 0 <= y < n and grid[x][y] == '1':
grid[x][y] = '#'
queue += [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
return num_islandsPythonComplexities
- Time Complexity:
O(MN), whereNis the width of the grid andMis the length of the grid. - Space Complexity:
O(MN), whereNis the width of the grid andMis the length of the grid.
References
- LeetCode link: Number of Islands – LeetCode