864.shortest-path-to-get-all-keys.java 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import java.util.LinkedList;
  2. class Solution {
  3. class Node implements Comparable<Node> {
  4. int keys;
  5. int step;
  6. int y;
  7. int x;
  8. Node(int keys, int step, int y, int x) {
  9. this.keys = keys;
  10. this.step = step;
  11. this.y = y;
  12. this.x = x;
  13. }
  14. }
  15. int m;
  16. int n;
  17. int acc;
  18. char[][] map;
  19. final int[] dy = new int[]{0, 1, 0, -1};
  20. final int[] dx = new int[]{1, 0, -1, 0};
  21. public int shortestPathAllKeys(String[] grid) {
  22. if ((m = grid.length) == 0 || (n = grid[0].length()) == 0) return -1;
  23. LinkedList<Node> queue = new LinkedList<>();
  24. map = new char[m][n];
  25. for (int i = 0; i < m; i++) {
  26. map[i] = grid[i].toCharArray();
  27. for (int j = 0; j < n; j++) {
  28. char ch = map[i][j];
  29. if (ch == '@') queue.offer(new Node(0, 0, i, j));
  30. if ('a' <= ch && ch <= 'f') acc |= 1 << (ch - 'a');
  31. }
  32. }
  33. boolean[][][] used = new boolean[m][n][1 << 6];
  34. while (!queue.isEmpty()) {
  35. Node top = queue.poll();
  36. if (!isValidMove(top, used)) continue;
  37. used[top.y][top.x][top.keys] = true;
  38. char ch = map[top.y][top.x];
  39. if ('a' <= ch && ch <= 'f') top.keys |= 1 << (ch - 'a');
  40. if (top.keys == acc) return top.step;
  41. for (int i = 0; i < 4; i++) {
  42. Node next = new Node(top.keys, top.step + 1, top.y + dy[i], top.x + dx[i]);
  43. queue.offer(next);
  44. }
  45. }
  46. return -1;
  47. }
  48. private boolean isValidMove(Node node, boolean[][][] used) {
  49. if (node.y < 0 || m <= node.y || node.x < 0 || n <= node.x) return false; // Out of map
  50. if (used[node.y][node.x][node.keys]) return false; // Visited
  51. char ch = map[node.y][node.x];
  52. if (ch == '#') return false; // Wall
  53. if ('A' <= ch && ch <= 'F') return ((1 << (ch - 'A')) & node.keys) != 0; // Has no key
  54. return true;
  55. }
  56. }