我正在尝试解决下面示例给出的leetcode问题。 例如:
[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]
我的方法是找到一个岛屿的一部分并穿过其相邻的细胞。有时我无法统计所有邻居。我相信这是由于这两件事之一: - 当我访问他们时擦除细胞 - 递归地解决这个问题 从逻辑上讲,擦除一个单元格并递归遍历其周围的邻居是有意义的,但我偶尔会失败,如下所示。
[[1,1,1,1],
[1,0,0,1],
[1,0,0,1],
[1,1,1,1]]
我返回26而不是24。
我确信这是因为细胞的连接方式。我只是弄清楚为什么逻辑没有意义。理论上,答案应该是岛屿数量* 4 - 邻居数量* 2 ,但我的算法无法统计一个邻居。在像
这样的问题[[0,0,0,0],
[1,1,1,1],
[1,1,1,1],
[1,1,1,1]]
我返回26而不是14!再次,我失去了邻居
class Solution(object):
def islandPerimeter(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
p = {}
p[0]=0
def perimeter(i, j):
if (grid[i][j]):
p[0]=p[0]+4
grid[i][j]=0
if(i-1>-1):
if (grid[i-1][j]):
p[0]=p[0]-2
perimeter(i-1,j)
if(j-1>-1):
if (grid[i][j-1]):
p[0]=p[0]-2
perimeter(i,j-1)
if(j+1<len(grid[0])):
if (grid[i][j+1]):
p[0]=p[0]-2
perimeter(i,j+1)
if (i+1<len(grid)):
if (grid[i+1][j]):
p[0]=p[0]-2
perimeter(i+1,j)
for i in range (0, len(grid)):
for j in range (0,len(grid[0])):
if (grid[i][j]):
perimeter(i,j)
return p[0]
return 0
答案 0 :(得分:1)
当我查看网格和黄色边界时,我立即将线段视为图形的边缘,其中顶点是网格的(x,y)坐标。
所以,我解决这个问题的方法是在(无向)图中用4个边来表示占用的正方形。
如果从左到右从上到下扫描占用的单元格,您只需要切换每个单元格的4条边(即如果它不存在则创建边缘,或者如果存在边缘则移除边缘)
这个解决方案很容易用文字描述,并且易于翻译成代码,结果代码看起来很容易阅读(在我看来,但这是主观的)。
def to_graph(map):
g={}
def toggle_edge(e1, e2):
e = tuple(sorted((e1, e2)))
if e in g: del g[e]
else: g[e] = 1
for i, row in enumerate(map):
for j, val in enumerate(row):
if val:
toggle_edge((i,j), (i,j+1))
toggle_edge((i,j+1), (i+1,j+1))
toggle_edge((i+1,j+1), (i+1,j))
toggle_edge((i+1,j), (i,j))
return g
要获得解的值,我们只计算图中的边数。
print(sum(to_graph([[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]).values()))
# 16
print(sum(to_graph([[1,1,1,1],
[1,0,0,1],
[1,0,0,1],
[1,1,1,1]]).values()))
# 24
print(sum(to_graph([[0,0,0,0],
[1,1,1,1],
[1,1,1,1],
[1,1,1,1]]).values()))
# 14
对不起,我没有查看您的代码,因为没有一些评论就不容易理解。