Approach
Breadth-first search
For Shortest Path to Get All Keys, the implementation explores reachable states in layers, which is the standard shape for unweighted shortest paths and minimum-step transitions.
- Model each valid configuration as a state and each legal move as an edge.
- Seed the queue with the starting state and mark it immediately.
- Expand each state once, recording distance or reachability for unseen neighbours.
Code notes
- 67 lines of Java from the credited upstream file 864.java.
- The implementation visibly relies on sequence storage, work queue.
- 6 loop blocks detected.
Complexity
Verify that each state and transition is processed only a bounded number of times; that determines the traversal cost.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class T {2 public int i;3 public int j;4 public int keys; 5 public T(int i, int j, int keys) {6 this.i = i;7 this.j = j;8 this.keys = keys;9 }10}11 12class Solution {13 public int shortestPathAllKeys(String[] grid) {14 final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};15 final int m = grid.length;16 final int n = grid[0].length();17 final int keysCount = getKeysCount(grid);18 final int KEYS = (1 << keysCount) - 1;19 final int[] start = getStart(grid);20 Queue<T> q = new ArrayDeque<>(List.of(new T(start[0], start[1], 0)));21 boolean[][][] seen = new boolean[m][n][KEYS];22 seen[start[0]][start[1]][0] = true;23 24 for (int step = 1; !q.isEmpty(); ++step)25 for (int sz = q.size(); sz > 0; --sz) {26 final int i = q.peek().i;27 final int j = q.peek().j;28 final int keys = q.poll().keys;29 for (int[] dir : DIRS) {30 final int x = i + dir[0];31 final int y = j + dir[1];32 if (x < 0 || x == m || y < 0 || y == n)33 continue;34 final char c = grid[x].charAt(y);35 if (c == '#')36 continue;37 final int newKeys = 'a' <= c && c <= 'f' ? keys | 1 << c - 'a' : keys;38 if (newKeys == KEYS)39 return step;40 if (seen[x][y][newKeys])41 continue;42 if ('A' <= c && c <= 'F' && (newKeys >> c - 'A' & 1) == 0)43 continue;44 q.offer(new T(x, y, newKeys));45 seen[x][y][newKeys] = true;46 }47 }48 49 return -1;50 }51 52 private int getKeysCount(String[] grid) {53 int count = 0;54 for (final String s : grid)55 count += (int) s.chars().filter(c -> 'a' <= c && c <= 'f').count();56 return count;57 }58 59 private int[] getStart(String[] grid) {60 for (int i = 0; i < grid.length; ++i)61 for (int j = 0; j < grid[0].length(); ++j)62 if (grid[i].charAt(j) == '@')63 return new int[] {i, j};64 throw new IllegalArgumentException();65 }66}67