I am on my second iteration of the famous "Number Of Islands" graph problem on Leetcode.
https://leetcode.com/problems/number-of-islands/
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.
Example 1:
Input: grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
Output: 1
Example 2:
Input: grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
Output: 3
My approach is to iterate through each cell in the grid, incrementing a counter when the value == 1. Then, do a breadth-first search of the cell's neighbors, adding them to the queue if their value == 1. Once the queue is empty, keep iterating through all the cells.
To avoid infinite loops, I first used a set()
to keep track of a list of tuple coordinates. This seemed to jack up my memory usage, so I then improved the algorithm by removing the set and simply setting the value of visited cells to 0.
I passed all the test cases but still can't figure out how to get a better runtime. I'm currently slower than ~90% of python submissions.
I would appreciate if anyone can help speed this thing up!
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
"""
Gets the neighbors of a coordinate in a grid. Returns a list of tuples.
"""
m = len(grid)
n = len(grid[0])
def get_neighbors(coord: Tuple[int, int]) -> List[Tuple]:
delta_row = [0, 1, 0, -1]
delta_column = [1, 0, -1, 0]
neighbors = []
for i in range(len(delta_row)):
new_x = coord[0] + delta_row[i]
new_y = coord[1] + delta_column[i]
if -1 < new_x < m and -1 < new_y < n:
neighbors.append((new_x, new_y))
return neighbors
# loop through the entire grid and set coords to 0 as we visit them
# if val == 1, do a breadth-first search for neighbors and increment islands
# if val == 0, continue to next coordinate.
islands = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
coord = (i, j)
if grid[coord[0]][coord[1]] == "1":
islands += 1
# breadth-first search
q = deque([coord])
while len(q) > 0:
c = q.popleft()
grid[c[0]][c[1]] = "0"
for neighbor in get_neighbors(c):
if grid[neighbor[0]][neighbor[1]] == "1":
q.append(neighbor)
grid[neighbor[0]][neighbor[1]] = "0"
return islands