岛屿周边 - 未计算网格中的所有邻居

时间:2018-04-18 13:54:59

标签: python backtracking

我正在尝试解决下面示例给出的leetcode问题。 例如:

[[0,1,0,0],  
 [1,1,1,0],  
 [0,1,0,0],  
 [1,1,0,0]]  

答案:16 说明:周边是下图中的16条黄色条纹: enter image description here

我的方法是找到一个岛屿的一部分并穿过其相邻的细胞。有时我无法统计所有邻居。我相信这是由于这两件事之一: - 当我访问他们时擦除细胞 - 递归地解决这个问题 从逻辑上讲,擦除一个单元格并递归遍历其周围的邻居是有意义的,但我偶尔会失败,如下所示。

[[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

1 个答案:

答案 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

对不起,我没有查看您的代码,因为没有一些评论就不容易理解。