Your code is somewhat Pythonic, but could use some improvements.
You seem to be under the impression that you are exploring each island by performing a breadth-first-search using a queue (named q
). Actually, you are performing a depth-first-search using a stack. (You can't .pop()
a queue!)
for _,d in enumerate(dirs)
is a pointless use of enumerate()
, and it should be written as for d in dirs
.
If you name the bounds as rlen
and clen
, then I would prefer that you use r
and c
(instead of i
and j
) for your coordinates.
Your add_dir()
function is a bit clumsy. You return (-1, -1)
if the result is out of bounds, which means that the caller also has to check whether the result is out of bounds. What you want is a neighbors(r, c)
function that lists all of the neighbor coordinates of (r, c) that are in bounds. One Pythonic technique that you can use is to write it as a generator. Another trick is to use chained comparisons (e.g. x < y <= z
).
It's a bit uncouth to initialize the elements of visited
to 0
, then set some of them to True
, mixing integers with booleans.
A more readable way to express the goal of the max_area_of_island()
function would be:
return max(island_size(r, c) for r, c in product(range(rlen), range(clen)))
… taking advantage of itertools.product()
to avoid a nested loop. I have therefore reorganized the code to provide an island_size()
function to enable that.
from itertools import productdef max_area_of_island(grid): rlen, clen = len(grid), len(grid[0]) def neighbors(r, c):""" Generate the neighbor coordinates of the given row and column that are within the bounds of the grid.""" for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: if (0 <= r + dr < rlen) and (0 <= c + dc < clen): yield r + dr, c + dc visited = [[False] * clen for _ in range(rlen)] def island_size(r, c):""" Find the area of the land connected to the given coordinate. Return 0 if the coordinate is water or if it has already been explored in a previous call to island_size().""" if grid[r][c] == 0 or visited[r][c]: return 0 area = 1 stack = [(r, c)] visited[r][c] = True while stack: for r, c in neighbors(*stack.pop()): if grid[r][c] and not visited[r][c]: stack.append((r, c)) visited[r][c] = True area += 1 return area return max(island_size(r, c) for r, c in product(range(rlen), range(clen)))