cs: add «1905. Count Sub Islands»

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2024-08-28 23:37:45 +02:00
parent b907b58d85
commit 4856bc8f3e
Signed by: mfocko
SSH key fingerprint: SHA256:icm0fIOSJUpy5+1x23sfr+hLtF9UhY8VpMC7H4WFJP8

110
cs/count-sub-islands.cs Normal file
View file

@ -0,0 +1,110 @@
public class Solution {
private static readonly int WATER = 0;
private static readonly int ISLAND = 1;
private static readonly List<(int dy, int dx)> DIRECTIONS = [
(1, 0),
(-1, 0),
(0, 1),
(0, -1)
];
private static void RunBFS(int[][] grid, int y0, int x0, int mark) {
var q = new Queue<(int y, int x)>();
// Handle the start
grid[y0][x0] = mark;
q.Enqueue((y0, x0));
while (q.TryDequeue(out var next)) {
var (y, x) = next;
foreach (var (dy, dx) in DIRECTIONS) {
var nextY = y + dy;
var nextX = x + dx;
if (nextY < 0 || nextY >= grid.Length || nextX < 0 || nextX >= grid[nextY].Length) {
continue;
}
if (grid[nextY][nextX] != ISLAND) {
continue;
}
grid[nextY][nextX] = mark;
q.Enqueue((nextY, nextX));
}
}
}
private void MarkIslands(int[][] grid) {
int mark = 1;
for (int y = 0; y < grid.Length; ++y) {
for (int x = 0; x < grid[y].Length; ++x) {
if (grid[y][x] == ISLAND) {
RunBFS(grid, y, x, ++mark);
}
}
}
}
private bool CheckSubIsland(int[][] grid1, int[][] grid2, int y0, int x0) {
if (grid1[y0][x0] == WATER || grid2[y0][x0] == WATER) {
return false;
}
var q = new Queue<(int y, int x)>();
// Handle the start; sink the island to optimize for time complexity
var expectedMark = grid1[y0][x0];
grid2[y0][x0] = WATER;
q.Enqueue((y0, x0));
var isSubIsland = true;
while (q.TryDequeue(out var next)) {
var (y, x) = next;
foreach (var (dy, dx) in DIRECTIONS) {
var nextY = y + dy;
var nextX = x + dx;
// bounds
if (nextY < 0 || nextY >= grid2.Length || nextX < 0 || nextX >= grid2[nextY].Length) {
continue;
}
// island continuation
if (grid2[nextY][nextX] != ISLAND) {
continue;
}
// check if the mark matches
if (grid1[nextY][nextX] != expectedMark) {
isSubIsland = false;
}
// sink to optimize
grid2[nextY][nextX] = WATER;
q.Enqueue((nextY, nextX));
}
}
return isSubIsland;
}
public int CountSubIslands(int[][] grid1, int[][] grid2) {
MarkIslands(grid1);
int subislands = 0;
for (int y = 0; y < grid2.Length; ++y) {
for (int x = 0; x < grid2[y].Length; ++x) {
if (CheckSubIsland(grid1, grid2, y, x)) {
++subislands;
}
}
}
return subislands;
}
}