The algorithm for this problem is not so hard to figure out.
This is a problem of finding the length of the shortest path in graph. As I mentioned in my previous article, BFS is a good way to slove this kind of problem.
This problem is a little different, it‘s no begining point but beginning points. So before the real BFS, we should find all points in one island. Then we can begin our bfs with a queue which contains all points of one island.
It‘s marked as medium in leetcode, but the recommended solution has 81 lines. And after some inspection on discuss articles, I found that most solutions exceed 40 lines. It‘s really not easy to get AC once with that many code. So I think hard is a more accurate label for this problem.
class Solution {
public int shortestBridge(int[][] A) {
int M = A.length, N = A[0].length;
int i = 0;
for (i = 0; i < M * N; ++i) {
if (A[i / N][i % N] == 1) break;
}
Map<Integer, Integer> s = new HashMap<>();
Queue<Integer> q = new LinkedList<>();
q.add(i);
s.put(i, 1);
int[][] moves = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
while (!q.isEmpty()) {
Integer pos = q.poll();
int x = pos / N, y = pos % N;
for (int[] move: moves) {
int nx = x + move[0], ny = y + move[1];
if (nx >= 0 && ny >= 0 && nx < M && ny < N) {
int val = nx * N + ny;
if (s.get(val) == null && A[nx][ny] == 1) {
s.put(val, 1);
q.add(val);
}
}
}
}
q.addAll(s.keySet());
while (!q.isEmpty()) {
Integer pos = q.poll();
Integer mark = s.get(pos);
int x = pos / N, y = pos % N;
for (int[] move: moves) {
int nx = x + move[0], ny = y + move[1];
if (nx >= 0 && ny >= 0 && nx < M && ny < N) {
int val = nx * N + ny;
if (s.get(val) == null) {
if (A[nx][ny] == 0) {
s.put(val, mark + 1);
q.add(val);
}
else {
return mark - 1;
}
}
}
}
}
return -1;
}
}
原文地址:https://www.cnblogs.com/exhausttolive/p/10604148.html