934. Shortest Bridge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Solution {
private static class Cell {
private final int i;
private final int j;

public Cell(int i, int j) {
this.i = i;
this.j = j;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cell cell = (Cell) o;
return i == cell.i && j == cell.j;
}

@Override
public int hashCode() {
return Objects.hash(i, j);
}
}

private static final int[][] DIRECTIONS = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

public int shortestBridge(int[][] grid) {
int n = grid.length;

Set<Cell> set2 = new HashSet<>();
Set<Cell> set3 = new HashSet<>();

for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
if (set2.isEmpty()) {
dfs(set2, grid, i, j);
} else {
set3.add(new Cell(i, j));
grid[i][j] = 3;
}
}
}
}

int bridge = 0;
while (!set2.isEmpty() && !set3.isEmpty()) {
for (Cell cell : set2) {
if (set3.contains(cell)) {
return bridge - 1; // 注意相交时已经多连接了一个点
}
}
Set<Cell> nextSet = new HashSet<>();
boolean useSet2 = set2.size() <= set3.size();
Set<Cell> minSet = useSet2 ? set2 : set3;
for (Cell cell : minSet) {
for (int[] direction : DIRECTIONS) {
int nextI = cell.i + direction[0], nextJ = cell.j + direction[1];
if (nextI >= 0 && nextI < n && nextJ >= 0 && nextJ < n &&
(useSet2 ? grid[nextI][nextJ] != 2 : grid[nextI][nextJ] != 3)) {
nextSet.add(new Cell(nextI, nextJ));
grid[nextI][nextJ] = useSet2 ? 2 : 3;
}
}
}

if (useSet2) {
set2 = nextSet;
} else {
set3 = nextSet;
}
bridge++;
}

return Integer.MAX_VALUE;
}

private void dfs(Set<Cell> set, int[][] grid, int i, int j) {
int n = grid.length;

set.add(new Cell(i, j));
grid[i][j] = 2;

for (int[] direction : DIRECTIONS) {
int nextI = i + direction[0], nextJ = j + direction[1];
if (nextI >= 0 && nextI < n && nextJ >= 0 && nextJ < n && grid[nextI][nextJ] == 1) {
dfs(set, grid, nextI, nextJ);
}
}
}
}

References

934. Shortest Bridge