Skip to content

Commit c919311

Browse files
committed
Update
1 parent eca146b commit c919311

File tree

2 files changed

+121
-2
lines changed

2 files changed

+121
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![DSA Learning](https://img.shields.io/badge/DSA-Learning-blue?style=for-the-badge&logo=leetcode)
44

5-
This repository contains solutions for 511 DSA problems from the [LeetCode](https://leetcode.com/)
5+
This repository contains solutions for 512 DSA problems from the [LeetCode](https://leetcode.com/)
66
website.
77

88
Problems are separated into 19 topics:
@@ -16,7 +16,7 @@ Problems are separated into 19 topics:
1616
| 5 | Binary Tree | [binary_tree](src/binary_tree) | 45 |
1717
| 6 | Design | [design](src/design) | 17 |
1818
| 7 | Dynamic Programming | [dynamic_programming](src/dynamic_programming) | 45 |
19-
| 8 | Graph | [graph](src/graph) | 63 |
19+
| 8 | Graph | [graph](src/graph) | 64 |
2020
| 9 | Greedy Algorithms | [greedy](src/greedy) | 20 |
2121
| 10 | Heap | [heap](src/heap) | 18 |
2222
| 11 | Interval | [interval](src/interval) | 11 |
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package graph;
2+
3+
import java.util.LinkedList;
4+
import java.util.Queue;
5+
6+
/**
7+
* Description: https://leetcode.com/problems/shortest-path-to-get-all-keys
8+
* Difficulty: Hard
9+
* Time complexity: O(2^k * m * n)
10+
* Space complexity: O(2^k * m * n)
11+
*/
12+
public class ShortestPathToGetAllKeys {
13+
14+
private final int[][] directions = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
15+
16+
public int shortestPathAllKeys(String[] lines) {
17+
char[][] grid = toGrid(lines);
18+
19+
int keysNumber = 0;
20+
int x = -1;
21+
int y = -1;
22+
for (int i = 0; i < grid.length; i++) {
23+
for (int j = 0; j < grid[0].length; j++) {
24+
if (isKey(grid[i][j])) {
25+
keysNumber++;
26+
} else if (isStart(grid[i][j])) {
27+
x = i;
28+
y = j;
29+
}
30+
}
31+
}
32+
33+
return findShortestPath(grid, keysNumber, x, y);
34+
}
35+
36+
private int findShortestPath(char[][] grid, int keysNumber, int x, int y) {
37+
// 1 << 5 - 1 = 100000 - 1 = 11111
38+
int allKeysFoundMask = (1 << keysNumber) - 1;
39+
40+
// we may visit the same node multiple times with a different set of keys
41+
int[][][] visited = new int[grid.length][grid[0].length][allKeysFoundMask];
42+
visited[x][y][0] = 1;
43+
44+
Queue<Node> planned = new LinkedList<>();
45+
planned.offer(new Node(x, y, 0));
46+
47+
int distance = 0;
48+
while (!planned.isEmpty()) {
49+
int levelSize = planned.size();
50+
distance++;
51+
52+
for (int i = 0; i < levelSize; i++) {
53+
Node current = planned.poll();
54+
55+
for (int[] dir : directions) {
56+
int x1 = current.x + dir[0];
57+
int y1 = current.y + dir[1];
58+
59+
if (!isValid(x1, y1, grid) || isWall(grid[x1][y1])) continue;
60+
61+
char next = grid[x1][y1];
62+
int mask = current.mask;
63+
64+
// we have no key for this lock, e.g:
65+
// 1. mask = 1001 -> we have 'a' and 'd' keys
66+
// 2. lock = 'B' -> 'B' - 'A' = 1
67+
// 3. mask >> 1 = 1001 >> 1 = 100
68+
// 4. 100 & 1 == 0 -> locked
69+
if (isLock(next) && (mask >> (next - 'A') & 1) == 0) continue;
70+
71+
// found a key
72+
if (isKey(next)) {
73+
mask = mask | (1 << (next - 'a'));
74+
if (mask == allKeysFoundMask) return distance;
75+
}
76+
77+
if (visited[x1][y1][mask] == 0) {
78+
planned.offer(new Node(x1, y1, mask));
79+
visited[x1][y1][mask] = 1;
80+
}
81+
}
82+
}
83+
}
84+
85+
return -1;
86+
}
87+
88+
private boolean isValid(int x, int y, char[][] grid) {
89+
return x >= 0 && y >= 0 && x < grid.length && y < grid[0].length;
90+
}
91+
92+
private boolean isKey(char c) {
93+
return Character.isLowerCase(c);
94+
}
95+
96+
private boolean isLock(char c) {
97+
return Character.isUpperCase(c);
98+
}
99+
100+
private boolean isStart(char c) {
101+
return c == '@';
102+
}
103+
104+
private boolean isWall(char c) {
105+
return c == '#';
106+
}
107+
108+
private char[][] toGrid(String[] lines) {
109+
char[][] grid = new char[lines.length][lines[0].length()];
110+
for (int i = 0; i < lines.length; i++) {
111+
grid[i] = lines[i].toCharArray();
112+
}
113+
114+
return grid;
115+
}
116+
117+
private record Node(int x, int y, int mask) {
118+
}
119+
}

0 commit comments

Comments
 (0)