Input: grid = [[0,1,1,0],[0,1,1,0],[0,0,0,0]]
Output: 2
Explanation: We need at least 2 days to get a disconnected grid.
Change land grid[1][1] and grid[0][2] to water and get 2 disconnected island.
Input: grid = [[1,1]]
Output: 2
Explanation: Grid of full water is also disconnected ([[1,1]] -> [[0,0]]), 0 islands.
class Solution {
int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int[][] dis, low;
int time, size;
public int minDays(int[][] grid) {
// Count number of islands
boolean[][] visited = new boolean[grid.length][grid[0].length];
int count = 0;
int x = -1, y = -1;
size = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
count++;
dfs(grid, visited, i, j);
// x & y are just used to store one pint of the island
// for articulation point
x = i;
y = j;
}
}
}
if (count == 0 || count > 1)
return 0;
if (size <= 2)
return size;
// Check for articulation point
time = 0;
dis = new int[grid.length][grid[0].length];
low = new int[grid.length][grid[0].length];
visited = new boolean[grid.length][grid[0].length];
boolean isPresent = findAP(grid, visited, x, y, -1, -1);
if (isPresent)
return 1;
// Else : Only 2 parts need to be removed to convert into multi islands
return 2;
}
public boolean findAP(int[][] grid, boolean[][] visited, int x, int y, int px, int py) {
time++;
visited[x][y] = true;
low[x][y] = time;
dis[x][y] = time;
int dfsCalls = 0;
boolean AP = false;
for (int[] dir : dirs) {
int i = x + dir[0], j = y + dir[1];
if (i == px && j == py)
continue;
if (i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && grid[i][j] == 1) {
if (visited[i][j])
low[x][y] = Math.min(low[x][y], dis[i][j]);
else {
AP = AP || findAP(grid, visited, i, j, x, y);
low[x][y] = Math.min(low[x][y], low[i][j]);
dfsCalls++;
// Additional conditions for starting node
if (dis[x][y] <= low[i][j] && px != -1 && py != -1)
AP = true;
}
}
}
// If it is the starting node
if (px == -1 && py == -1 && dfsCalls > 1)
AP = true;
return AP;
}
public void dfs(int[][] grid, boolean[][] visited, int x, int y) {
size++;
visited[x][y] = true;
for (int[] dir : dirs) {
int i = x + dir[0], j = y + dir[1];
if (i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && !visited[i][j] && grid[i][j] == 1) {
dfs(grid, visited, i, j);
}
}
}
}