-
Notifications
You must be signed in to change notification settings - Fork 46
/
_864.java
74 lines (64 loc) · 2.68 KB
/
_864.java
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
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;
/**
* LeetCode 864 - Shortest Path to Get All Keys
* <p>
* SPFA
*/
public class _864 {
int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
public int shortestPathAllKeys(String[] grid) {
int r = grid.length, c = grid[0].length();
char[][] g = new char[r][];
for (int i = 0; i < r; i++) {
g[i] = grid[i].toCharArray();
}
final int INF = Integer.MAX_VALUE / 2;
int[][][] dist = new int[r][c][1 << 6];
boolean[][][] inQueue = new boolean[r][c][1 << 6];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
Arrays.fill(dist[i][j], INF);
int ans = INF;
int numKeys = 0;
Queue<int[]> queue = new ArrayDeque<>();
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
char ch = g[i][j];
if (ch == '@') {
dist[i][j][0] = 0;
inQueue[i][j][0] = true;
queue.add(new int[]{i, j, 0});
} else if (Character.isLowerCase(ch)) {
numKeys = Math.max(numKeys, ch - 'a' + 1);
}
}
while (!queue.isEmpty()) {
int x = queue.peek()[0], y = queue.peek()[1], keysInHand = queue.poll()[2];
// System.out.println(x + " " + y + " " + keysInHand + " " + dist[x][y][keysInHand]);
inQueue[x][y][keysInHand] = false;
for (int k = 0; k < 4; k++) {
int xx = x + dx[k], yy = y + dy[k];
if (xx >= 0 && xx < r && yy >= 0 && yy < c) {
char ch = g[xx][yy];
if (ch == '@' || ch == '.' || Character.isLowerCase(ch) || (Character.isUpperCase(ch) && ((1 << (ch - 'A')) & keysInHand) != 0)) {
int newKeysInHand = Character.isLowerCase(ch) ? keysInHand | (1 << (ch - 'a')) : keysInHand;
if (dist[x][y][keysInHand] + 1 < dist[xx][yy][newKeysInHand]) {
dist[xx][yy][newKeysInHand] = dist[x][y][keysInHand] + 1;
if (!inQueue[xx][yy][newKeysInHand]) {
inQueue[xx][yy][newKeysInHand] = true;
queue.add(new int[]{xx, yy, newKeysInHand});
}
if (newKeysInHand == (1 << numKeys) - 1) {
ans = Math.min(ans, dist[xx][yy][newKeysInHand]);
}
}
}
}
}
}
return ans < INF ? ans : -1;
}
}