0% completed
Problem Statement
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.
Examples
Example 1:
- Input: grid =
[[1, 1, 0], [1, 1, 0], [0, 1, 1]]
- Expected Output:
1
- Justification: Changing any of the land cells in the first island (like
grid[1][1]
orgrid[2][1]
) will break the connection, creating two separate islands or making it impossible to connect. Therefore, only one day is needed.
Example 2:
- Input: grid =
[[1, 0, 0, 1], [0, 1, 1, 0], [1, 0, 0, 1]]
- Expected Output:
0
- Justification: There are a total 5 islands. So, we don't need
0
days to disconnect them.
Example 3:
- Input: grid =
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
- Expected Output:
2
- Justification: We need
2
days to change land to water cell at positiongrid[0][1]
andgrid[1][0]
.
Solution
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.
Step-by-Step Algorithm
-
Initialize Variables:
- Set
numRows
to the number of rows in the grid andnumCols
to the number of columns. - Create an instance of
IslandSeparationInfo
namedseparationInfo
to keep track of whether an articulation point (critical point) is found (hasCriticalPoint
) and the discovery time (discoveryTime
). - Define 2D arrays
discoveryTime
,lowestTimeReachable
, andparentCell
to store the discovery time, lowest reachable discovery time, and parent cell in the DFS tree for each cell in the grid. - Initialize
totalLandCells
andtotalIslands
to zero.
- Set
-
Set Default Values:
- Loop through each cell in the grid and set the values of
discoveryTime
,lowestTimeReachable
, andparentCell
to-1
to indicate that these cells are unvisited and undefined.
- Loop through each cell in the grid and set the values of
-
Count Islands and Perform DFS:
- Loop through each cell in the grid:
- For every land cell (
grid[row][col] == 1
), incrementtotalLandCells
. - If the cell has not been visited (
discoveryTime[row][col] == -1
), initiate a DFS from this cell by callingfindCriticalPoints
function. - Each DFS traversal identifies articulation points and counts the number of islands. Increment
totalIslands
after each DFS traversal.
- For every land cell (
- Loop through each cell in the grid:
-
Determine Minimum Days to Disconnect:
- Check the total number of islands:
- If
totalIslands
is0
or greater than1
, return0
(the grid is already disconnected). - If there is only one land cell (
totalLandCells == 1
), return1
(one day is sufficient to disconnect the grid). - If an articulation point (
hasCriticalPoint
) is found, return1
(removing the critical point will disconnect the grid). - Otherwise, return
2
(disconnecting the grid will require removing at least two land cells).
- If
- Check the total number of islands:
-
Depth-First Search for Articulation Points (
findCriticalPoints
):- Set the discovery time of the current cell (
discoveryTime[row][col]
) to the current discovery time fromseparationInfo
. - Increment the global discovery time (
separationInfo.discoveryTime
). - Initialize the lowest reachable time of the current cell (
lowestTimeReachable[row][col]
) to its discovery time. - Set
childCount
to0
to keep track of the number of child nodes for this DFS. - Explore all four possible directions (right, down, left, up):
- For each valid adjacent land cell that hasn't been visited:
- Increment
childCount
. - Set the parent of the adjacent cell to the current cell.
- Recursively call
findCriticalPoints
on the adjacent cell. - After returning from recursion, update the lowest reachable time for the current cell using the child’s lowest reachable time.
- Check if the current cell is a critical point. If the lowest reachable time of the child is greater than or equal to the discovery time of the current cell and it's not the root, mark it as an articulation point. It means current cell doesn't have any back edge.
- Increment
- For already visited adjacent cells that are not the parent of the current cell, update the lowest reachable time of the current cell using the discovery time of the adjacent cell. Here, we ignore back edge to the parent cell.
- For each valid adjacent land cell that hasn't been visited:
- After checking all directions, if the current cell is the root of the DFS tree and has more than one child, mark it as an articulation point.
- Set the discovery time of the current cell (
-
Utility Function (
isValidLand
):- Check if a given cell is within the bounds of the grid and is a land cell (
1
).
- Check if a given cell is within the bounds of the grid and is a land cell (
Algorithm Walkthrough
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 withhasCriticalPoint = false
,discoveryTime = 0
.discoveryTime
,lowestTimeReachable
, andparentCell
arrays are all initialized to-1
.
-
Set Default Values:
- All cells in
discoveryTime
,lowestTimeReachable
, andparentCell
are set to-1
.
- All cells in
-
Count Islands and Perform DFS:
- Start at
grid[0][0]
(first cell, which is land1
):- Increment
totalLandCells
to1
. - Since
discoveryTime[0][0] == -1
, start DFS from this cell.
- Increment
- Start at
-
DFS from
grid[0][0]
:- Set
discoveryTime[0][0] = 0
, increment globaldiscoveryTime
to1
. - Set
lowestTimeReachable[0][0] = 0
. - Explore adjacent cells:
- Right to
grid[0][1]
(land1
):- Increment child count to
1
. - Start DFS from
grid[0][1]
. - Set
discoveryTime[0][1] = 1
, increment globaldiscoveryTime
to2
. - Set
lowestTimeReachable[0][1] = 1
. - Explore further:
- Down to
grid[1][1]
(land1
):- Increment child count to
1
. - Start DFS from
grid[1][1]
. - Set
discoveryTime[1][1] = 2
, increment globaldiscoveryTime
to3
. - Set
lowestTimeReachable[1][1] = 2
. - Explore further:
- Down to
grid[2][1]
(land1
):- Increment child count to
1
. - Start DFS from
grid[2][1]
. - Set
discoveryTime[2][1] = 3
, increment globaldiscoveryTime
to4
. - Set
lowestTimeReachable[2][1] = 3
. - Explore further:
- Right to
grid[2][2]
(land1
):- Increment child count to
1
. - Start DFS from
grid[2][2]
. - Set
discoveryTime[2][2] = 4
, increment globaldiscoveryTime
to5
. - Set
lowestTimeReachable[2][2] = 4
. - No more valid cells to explore.
- Backtrack to
grid[2][1]
:- Update
lowestTimeReachable[2][1] = min(3, 4) = 3
.
- Update
- Check articulation point condition:
lowestTimeReachable[2][2] >= discoveryTime[2][1]
(4 >= 3) andparentCell[0][1] != -1
.- Mark
grid[2][1]
as an articulation point (separationInfo.hasCriticalPoint = true
).
- Increment child count to
- Right to
- Increment child count to
- Down to
- Increment child count to
- No more valid cells to explore.
- Backtrack to
grid[1][1]
:- Update
lowestTimeReachable[1][1] = min(2, 3) = 2
.- Check articulation point condition:
lowestTimeReachable[2][1] >= discoveryTime[1][1]
(3 >= 2) andparentCell[1][1] != -1
.
- Check articulation point condition:
- Mark
grid[1][1]
as an articulation point (separationInfo.hasCriticalPoint = true
).
- Update
- Backtrack to
grid[0][1]
:- Update
lowestTimeReachable[0][1] = min(1, 2) = 1
.
- Update
- Backtrack to
- Down to
- Increment child count to
- Back to
grid[0][0]
, continue exploration:- All nodes are visited.
- Right to
- Set
-
End of DFS:
- All cells are visited, and articulation points are found at
(2, 1)
and(1, 1)
.
- All cells are visited, and articulation points are found at
-
Final Decision:
- Since
hasCriticalPoint
is true, return1
day to disconnect the grid.
- Since
Output:
Output: 1
Code
Complexity Analysis
Time Complexity
- The time complexity of the solution is O((m * n)), where
m
is the number of rows andn
is the number of columns in the grid.- Depth-First Search (DFS): Each DFS traversal takes O(m * n) time in the worst case, as we may need to visit every cell in the grid.
- So, the overall time complexity of the algorithm is O(m * n).
Space Complexity
- The space complexity of the solution is O(m * n).
- This includes:
- Auxiliary Arrays:
discoveryTime
,lowestTimeReachable
, andparentCell
, each of which has a size ofm * n
. - Recursive Stack: The depth of the recursion can go up to O(m * n) in the worst case, depending on the layout of the grid.
- Auxiliary Arrays:
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible