0% completed
You are given a binary grid of size m x n
, where each cell can either be land (marked as 1
) or water (marked as 0
). An island is a group of connected land cells (1
s) that are adjacent either horizontally or vertically.
The grid is considered connected if it contains exactly one island.
In one day, we are allowed to change any single land cell 1
into a water cell 0
.
Return the minimum number of days to disconnect the grid.
Example 1:
[[1, 1, 0],
[1, 1, 0],
[0, 1, 1]]
1
grid[1][1]
or grid[2][1]
) will break the connection, creating two separate islands or making it impossible to connect. Therefore, only one day is needed.Example 2:
[[1, 0, 0, 1],
[0, 1, 1, 0],
[1, 0, 0, 1]]
0
0
days to disconnect them.Example 3:
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]
2
2
days to change land to water cell at position grid[0][1]
and grid[1][0]
.To solve this problem, we will use Tarjan's Algorithm for finding articulation points in a graph. In this problem, each land cell (1
) in the grid represents a vertex in the graph, and an edge exists between two vertices if their corresponding cells are adjacent (either horizontally or vertically). The goal is to find the minimum number of days required to disconnect the grid by turning land cells (1
) into water cells (0
).
Our approach involves running a Depth-First Search (DFS) on the grid to identify these articulation points. The DFS traversal allows us to calculate the discovery time (when a cell is first visited) and the lowest time reachable (the earliest visited vertex reachable from the subtree rooted at that cell). If an articulation point is found, the minimum number of days required to disconnect the grid is 1
; otherwise, we may need to turn two land cells into water to achieve disconnection. If there is more than one island initially or no land cells, the grid is already disconnected.
Initialize Variables:
numRows
to the number of rows in the grid and numCols
to the number of columns.IslandSeparationInfo
named separationInfo
to keep track of whether an articulation point (critical point) is found (hasCriticalPoint
) and the discovery time (discoveryTime
).discoveryTime
, lowestTimeReachable
, and parentCell
to store the discovery time, lowest reachable discovery time, and parent cell in the DFS tree for each cell in the grid.totalLandCells
and totalIslands
to zero.Set Default Values:
discoveryTime
, lowestTimeReachable
, and parentCell
to -1
to indicate that these cells are unvisited and undefined.Count Islands and Perform DFS:
grid[row][col] == 1
), increment totalLandCells
.discoveryTime[row][col] == -1
), initiate a DFS from this cell by calling findCriticalPoints
function.totalIslands
after each DFS traversal.Determine Minimum Days to Disconnect:
totalIslands
is 0
or greater than 1
, return 0
(the grid is already disconnected).totalLandCells == 1
), return 1
(one day is sufficient to disconnect the grid).hasCriticalPoint
) is found, return 1
(removing the critical point will disconnect the grid).2
(disconnecting the grid will require removing at least two land cells).Depth-First Search for Articulation Points (findCriticalPoints
):
discoveryTime[row][col]
) to the current discovery time from separationInfo
.separationInfo.discoveryTime
).lowestTimeReachable[row][col]
) to its discovery time.childCount
to 0
to keep track of the number of child nodes for this DFS.childCount
.findCriticalPoints
on the adjacent cell.Utility Function (isValidLand
):
1
).Let's demonstrate a step-by-step walkthrough for the input grid:
Input:
[[1, 1, 0],
[1, 1, 0],
[0, 1, 1]]
Steps:
Initialize Variables:
numRows = 3
, numCols = 3
.separationInfo
is initialized with hasCriticalPoint = false
, discoveryTime = 0
.discoveryTime
, lowestTimeReachable
, and parentCell
arrays are all initialized to -1
.Set Default Values:
discoveryTime
, lowestTimeReachable
, and parentCell
are set to -1
.Count Islands and Perform DFS:
grid[0][0]
(first cell, which is land 1
):
totalLandCells
to 1
.discoveryTime[0][0] == -1
, start DFS from this cell.DFS from grid[0][0]
:
discoveryTime[0][0] = 0
, increment global discoveryTime
to 1
.lowestTimeReachable[0][0] = 0
.grid[0][1]
(land 1
):
1
.grid[0][1]
.discoveryTime[0][1] = 1
, increment global discoveryTime
to 2
.lowestTimeReachable[0][1] = 1
.grid[1][1]
(land 1
):
1
.grid[1][1]
.discoveryTime[1][1] = 2
, increment global discoveryTime
to 3
.lowestTimeReachable[1][1] = 2
.grid[2][1]
(land 1
):
1
.grid[2][1]
.discoveryTime[2][1] = 3
, increment global discoveryTime
to 4
.lowestTimeReachable[2][1] = 3
.grid[2][2]
(land 1
):
1
.grid[2][2]
.discoveryTime[2][2] = 4
, increment global discoveryTime
to 5
.lowestTimeReachable[2][2] = 4
.grid[2][1]
:
lowestTimeReachable[2][1] = min(3, 4) = 3
.lowestTimeReachable[2][2] >= discoveryTime[2][1]
(4 >= 3) and parentCell[0][1] != -1
.grid[2][1]
as an articulation point (separationInfo.hasCriticalPoint = true
).grid[1][1]
:
lowestTimeReachable[1][1] = min(2, 3) = 2
.
lowestTimeReachable[2][1] >= discoveryTime[1][1]
(3 >= 2) and parentCell[1][1] != -1
.grid[1][1]
as an articulation point (separationInfo.hasCriticalPoint = true
).grid[0][1]
:
lowestTimeReachable[0][1] = min(1, 2) = 1
.grid[0][0]
, continue exploration:
End of DFS:
(2, 1)
and (1, 1)
.Final Decision:
hasCriticalPoint
is true, return 1
day to disconnect the grid.Output:
Output: 1
m
is the number of rows and n
is the number of columns in the grid.
discoveryTime
, lowestTimeReachable
, and parentCell
, each of which has a size of m * n
......
.....
.....