Suppose we have a binary matrix, where 0 represents water and 1 represents the land. An island is a group of connecting 1s in 4 directions. Islands are either surrounded by 0s (water) or by the edges. We have to find the length of shortest bridge that connects two islands.
So, if the input is like
0 | 0 | 1 |
1 | 0 | 1 |
1 | 0 | 0 |
then the output will be 1. This will connect (1,0) to (1,2) points.
To solve this, we will follow these steps −
row := row count of matrix
col := column count of matrix
Define a function dfs() . This will take i, j, s
if (i, j) is in s, then
return
if mat[i, j] is same as 0, then
return
insert (i, j) into s
if i - 1 >= 0, then
dfs(i - 1, j, s)
if i + 1 < row, then
dfs(i + 1, j, s)
if j - 1 >= 0, then
dfs(i, j - 1, s)
if j + 1 < col, then
dfs(i, j + 1, s)
From the main method do the following −
seen := a new set
for i in range 0 to row, do
if size of seen > 0, then
come out from the loop
for j in range 0 to col, do
if mat[i, j] is same as 1, then
dfs(i, j, seen)
come out from the loop
q := a double ended queue
for each land in seen, do
(i, j) := land
if i - 1 >= 0 and mat[i - 1, j] is same as 0, then
insert (i - 1, j, 1) at the end of q
if i + 1 < row and mat[i + 1, j] is same as 0, then
insert (i + 1, j, 1) at the end of q
if j - 1 >= 0 and mat[i, j - 1] is same as 0, then
insert (i, j - 1, 1) at the end of q
if j + 1 < col and mat[i, j + 1] is same as 0, then
insert (i, j + 1, 1) at the end of q
while size of q > 0, do
(i, j, dist) := left item of q, and delete item from left of q
if (i, j) is seen, then
go for next iteration
mark (i, j) as seen
if mat[i, j] is same as 1, then
return dist - 1
if i - 1 >= 0, then
insert (i - 1, j, dist + 1) at the end of q
if i + 1 < row is non-zero, then
insert (i + 1, j, dist + 1) at the end of q
if j - 1 >= 0, then
insert (i, j - 1, dist + 1) at the end of q
if j + 1 < col is non-zero, then
insert (i, j + 1, dist + 1) at the end of q
Example
Let us see the following implementation to get better understanding −
import collections class Solution: def solve(self, mat): row = len(mat) col = len(mat[0]) def dfs(i, j, s): if (i, j) in s: return if mat[i][j] == 0: return s.add((i, j)) if i - 1 >= 0: dfs(i - 1, j, s) if i + 1 < row: dfs(i + 1, j, s) if j - 1 >= 0: dfs(i, j - 1, s) if j + 1 < col: dfs(i, j + 1, s) seen = set() for i in range(row): if len(seen) > 0: break for j in range(col): if mat[i][j] == 1: dfs(i, j, seen) break q = collections.deque() for land in seen: i, j = land if i - 1 >= 0 and mat[i - 1][j] == 0: q.append((i - 1, j, 1)) if i + 1 < row and mat[i + 1][j] == 0: q.append((i + 1, j, 1)) if j - 1 >= 0 and mat[i][j - 1] == 0: q.append((i, j - 1, 1)) if j + 1 < col and mat[i][j + 1] == 0: q.append((i, j + 1, 1)) while len(q) > 0: i, j, dist = q.popleft() if (i, j) in seen: continue seen.add((i, j)) if mat[i][j] == 1: return dist - 1 if i - 1 >= 0: q.append((i - 1, j, dist + 1)) if i + 1 < row: q.append((i + 1, j, dist + 1)) if j - 1 >= 0: q.append((i, j - 1, dist + 1)) if j + 1 < col: q.append((i, j + 1, dist + 1)) ob = Solution() matrix = [ [0, 0, 1], [1, 0, 1], [1, 0, 0], ] print(ob.solve(matrix))
Input
[ [0, 0, 1], [1, 0, 1], [1, 0, 0], ]
Output
1