LeetCode刷题Python之934. 最短的桥

给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。

岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid 中 恰好存在两座岛 。

你可以将任意数量的 0 变为 1 ,以使两座岛连接起来,变成 一座岛 。

返回必须翻转的 0 的最小数目。

示例 1:

输入:grid = [[0,1],[1,0]]
输出:1
示例 2:

输入:grid = [[0,1,0],[0,0,0],[0,0,1]]
输出:2
示例 3:

输入:grid = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
输出:1
 

提示:

n == grid.length == grid[i].length
2 <= n <= 100
grid[i][j] 为 0 或 1
grid 中恰有两个岛

class Solution:
    def get_islands(self, A):

        def dfs(r, c, res:set):
            if (r, c) not in seen and 0 <= r < len(A) and 0 <= c < len(A[0]) and A[r][c]:
                res.add((r, c))
                seen.add((r, c))
                for nr, nc in [(r + 1, c), (r, c + 1), (r - 1, c), (r, c - 1)]:
                    dfs(nr, nc, res)
                return res

        islands = []
        seen = set()

        for r in range(len(A)):
            for c in range(len(A[0])):
                if (r, c) not in seen and A[r][c]:
                    islands.append(dfs(r, c, set()))
                seen.add((r, c))
        return islands

    def shortestBridge(self, A):
        R, C = len(A), len(A[0])

        def neighbors(r, c):
            for nr, nc in ((r-1,c),(r,c-1),(r+1,c),(r,c+1)):
                if 0 <= nr < R and 0 <= nc < C:
                    yield nr, nc

        island_1, island_2 = self.get_islands(A)
        queue = [(node, 0) for node in island_1]
        done = set(island_1)

        while queue:
            location, depth = queue.pop(0)
            if location in island_2:
                return depth-1
            for nei in neighbors(*location):
                if nei not in done:
                    queue.append((nei, depth+1))
                    done.add(nei)

s = Solution()
A = [[1, 1, 0, 0, 0, 0],
     [1, 1, 1, 0, 0, 0],
     [1, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 1, 0, 0],
     [0, 0, 0, 1, 1, 0],
     [0, 0, 0, 0, 0, 0],
     ]
# print(s.get_islands(A))
print(s.shortestBridge(A))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值