Skip to content

Commit 7739d86

Browse files
committed
ShortestPathToGetAllKeys864
1 parent b042b59 commit 7739d86

File tree

3 files changed

+122
-3
lines changed

3 files changed

+122
-3
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.class
22
.DS_store
3-
.vscode
3+
.vscode
4+
.idea

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@
5353
| [Graph](https://github.com/fluency03/leetcode-java/blob/master/src/graph) |
5454

5555

56-
# Total: 430
56+
# Total: 432
5757

5858
| Easy | Medium | Hard | - |
5959
|:-------:|:-------:|:----:|:-:|
60-
| 116 | 231 | 69 | 4 |
60+
| 116 | 231 | 71 | 4 |
6161

6262

6363
| Question | Solution | Difficulty |
@@ -481,6 +481,7 @@
481481
| [860. Lemonade Change](https://leetcode.com/problems/lemonade-change/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LemonadeChange860.java) | Easy |
482482
| [862. Shortest Subarray with Sum at Least K](https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestSubarrayWithSumAtLeastK862.java) | Hard |
483483
| [863. All Nodes Distance K in Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AllNodesDistanceKInBinaryTree863.java) | Medium |
484+
| [864. Shortest Path to Get All Keys](https://leetcode.com/problems/shortest-path-to-get-all-keys/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestPathToGetAllKeys864.java) | Hard |
484485
| [873. Length of Longest Fibonacci Subsequence](https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LengthOfLongestFibonacciSubsequence873.java) | Medium |
485486
| [875. Koko Eating Bananas](https://leetcode.com/problems/koko-eating-bananas/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KokoEatingBananas875.java) | Easy |
486487
| [876. Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MiddleOfTheLinkedList876.java) | Easy |

src/ShortestPathToGetAllKeys864.java

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* We are given a 2-dimensional grid. "." is an empty cell, "#" is a wall, "@"
3+
* is the starting point, ("a", "b", ...) are keys, and ("A", "B", ...) are
4+
* locks.
5+
*
6+
* We start at the starting point, and one move consists of walking one space
7+
* in one of the 4 cardinal directions. We cannot walk outside the grid, or
8+
* walk into a wall. If we walk over a key, we pick it up. We can't walk over
9+
* a lock unless we have the corresponding key.
10+
*
11+
* For some 1 <= K <= 6, there is exactly one lowercase and one uppercase
12+
* letter of the first K letters of the English alphabet in the grid. This
13+
* means that there is exactly one key for each lock, and one lock for each
14+
* key; and also that the letters used to represent the keys and locks were
15+
* chosen in the same order as the English alphabet.
16+
*
17+
* Return the lowest number of moves to acquire all keys.
18+
* If it's impossible, return -1.
19+
*
20+
* Example 1:
21+
* Input: ["@.a.#","###.#","b.A.B"]
22+
* Output: 8
23+
*
24+
* Example 2:
25+
* Input: ["@..aA","..B#.","....b"]
26+
* Output: 6
27+
*
28+
* Note:
29+
* 1 <= grid.length <= 30
30+
* 1 <= grid[0].length <= 30
31+
* grid[i][j] contains only '.', '#', '@', 'a'-'f' and 'A'-'F'
32+
* The number of keys is in [1, 6].
33+
* Each key has a different letter and opens exactly one lock.
34+
*/
35+
36+
public class ShortestPathToGetAllKeys864 {
37+
private int[][] directions = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
38+
39+
public int shortestPathAllKeys(String[] grid) {
40+
int M = grid.length;
41+
int N = grid[0].length();
42+
char[][] maze = new char[M][N];
43+
int numKeys = 0;
44+
int[] start = new int[2];
45+
for (int i=0; i<M; i++) {
46+
char[] row = grid[i].toCharArray();
47+
for (int j=0; j<N; j++) {
48+
maze[i][j] = row[j];
49+
if (row[j] == '@') {
50+
start[0] = i;
51+
start[1] = j;
52+
} else if (row[j] >= 'a' && row[j] <= 'f') {
53+
numKeys++;
54+
}
55+
}
56+
}
57+
58+
int[] res = new int[]{Integer.MAX_VALUE};
59+
Set<Character> keySet = new HashSet<>();
60+
helper(maze, start, numKeys, keySet, 0, M, N, res);
61+
return res[0] == Integer.MAX_VALUE ? -1 : res[0];
62+
}
63+
64+
public void helper(char[][] maze, int[] start, int numKeys, Set<Character> keySet, int steps, int M, int N, int[] res) {
65+
if (numKeys == keySet.size()) {
66+
res[0] = Math.min(res[0], steps);
67+
return;
68+
}
69+
boolean[][] visited = new boolean[M][N];
70+
Queue<int[]> q = new LinkedList<>();
71+
q.add(start);
72+
visited[start[0]][start[1]] = true;
73+
Set<int[]> newKeys = new HashSet<>();
74+
int level = 1;
75+
while (!q.isEmpty() && steps + level < res[0]) {
76+
int size = q.size();
77+
for (int i=0; i<size; i++) {
78+
int[] curr = q.poll();
79+
for (int[] dir: directions) {
80+
int x = curr[0] + dir[0];
81+
int y = curr[1] + dir[1];
82+
if (x < 0 || y < 0 || x >= M || y >= N) continue;
83+
char next = maze[x][y];
84+
if (next == '#' || visited[x][y]) continue;
85+
if (next == '@' || next == '.') {
86+
q.add(new int[]{x, y});
87+
visited[x][y] = true;
88+
} else if (next >= 'a' && next <= 'f') {
89+
if (!keySet.contains(next)) {
90+
newKeys.add(new int[]{x, y, level});
91+
} else {
92+
q.add(new int[]{x, y});
93+
visited[x][y] = true;
94+
}
95+
} else if (next >= 'A' && next <= 'F') {
96+
if (keySet.contains(Character.toLowerCase(next))) {
97+
q.add(new int[]{x, y});
98+
visited[x][y] = true;
99+
}
100+
}
101+
}
102+
}
103+
level++;
104+
}
105+
106+
if (!newKeys.isEmpty()) {
107+
for (int[] newKey: newKeys) {
108+
int[] newKeyPos = new int[]{newKey[0], newKey[1]};
109+
char key = maze[newKey[0]][newKey[1]];
110+
keySet.add(key);
111+
helper(maze, newKeyPos, numKeys, keySet, steps + newKey[2], M, N, res);
112+
keySet.remove(key);
113+
}
114+
}
115+
}
116+
117+
}

0 commit comments

Comments
 (0)