我是Python编码的新手,很难理解下面的代码。在图论上,使用DFS在所有岛屿区域中找到最大的区域。 1代表岛屿,0代表网格中的水。
def maxAreaOfIsland(grid):
row, col = len(grid), len(grid[0])
def dfs(i, j):
if 0 <= i <= row - 1 and 0 <= j <= col - 1 and grid[i][j]:
grid[i][j] = 0
#scans through all rows & cols and
#turns number in the grid into 0 if all conditions are true?
return 1 + dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
return 0
# recursive function that checks up, down, left, right in the grid.
# when does it return 1?
return max(dfs(i, j) for i in range(row) for j in range(col))
maxAreaOfIsland([[1,0,1,1,1],
[0,0,0,1,1],
[1,1,1,0,1]])
Out: 6
我添加了一些评论,这些评论反映了我到目前为止的理解,但不确定是否正确。从第4行开始,我很困惑,尤其是递归部分。 有人可以详细解释吗?通常,这类代码倾向于排队/出队,以记录是否已探访过该岛,但我认为该代码不具备该功能?
答案 0 :(得分:1)
我想这个问题实际上是关于理解算法而不是Python。提供的Python代码非常简单。
该代码包含函数maxAreaOfIsland
,该函数又包含递归函数dfs
。这两个函数构成2个计算层。让我们分别查看这些层。
# outer layer
def maxAreaOfIsland(grid):
row, col = len(grid), len(grid[0])
# function dfs() definition
return max(dfs(i, j) for i in range(row) for j in range(col))
因此,外层非常简单-为所有可能的dfs(i, j)
和i
计算j
,然后选择最大计算值。
# inner layer - slightly modified
def dfs(i, j):
# recursive case
if (0 <= i <= row - 1 and 0 <= j <= col - 1) and grid[i][j] == 1:
grid[i][j] = 0 # this is how we remember visited cells since we don't count zeros
# optional prints to look at the grid during computation
# print(i, j)
# print(*grid, sep='\n', end='\n\n')
count_current = 1
count_neighbors = dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
return count_current + count_neighbors
# trivial case and out-of-borders case
else:
return 0
内层稍微复杂一点。它能做什么? (1)它得到i
和j
。 (2)如果单元格包含0
,则说明情况很简单(水),或者我们不在网格中-只需返回0
。 (3)如果单元格包含1
,则它是递归的情况(land)-函数开始计算与给定单元格相邻的所有1
的数量,每个1
都变成{{ 1}},以避免重复计算。
您的示例网格具有3行(0、1、2)和5列(0、1、2、3、4)。假设我们在0
。是i = 0, j = 2
。我们将其计数(当前结果为1),将其变成1
并逐一查看其邻居-上一个邻居不在网格中,下一个邻居为0
,左邻居为{{1 }},右邻居是0
。我们不返回当前结果,而是继续进行右边的neigbor 0
。我们计算它(当前结果为2),将其变成1
并查看邻居。上一个邻居不在网格内,下一个邻居为i = 0, j = 3
。我们在这里停止,我们不返回当前结果,我们记得还有2个邻居,我们进入了底部的邻居0
。我们计算它(当前结果是3),将其变成1
并查看邻居。上一个邻居是i = 1, j = 3
。我们在这里停止,我们不返回当前结果,我们还记得大约3个邻居,我们进入了上一个邻居0
。依此类推。
我的建议是绘制一个简单的示例网格(用笔在一张纸上),并对其手动应用dfs算法。