Skip to content

Latest commit

 

History

History
154 lines (117 loc) · 5.89 KB

shortest_path_to_get_all_keys.md

File metadata and controls

154 lines (117 loc) · 5.89 KB

Solution -1

Explanation

This code implements a solution for finding the shortest path to collect all keys in a grid-based game. Here's an explanation of the code:

  1. The State class represents a state in the game grid, containing the current position (x, y), the number of steps taken so far, and the keys collected.

  2. The Solution class contains the shortestPathAllKeys method, which takes a grid represented as a list of strings and returns the length of the shortest path to collect all keys.

  3. The directions list represents the possible movement directions: up, down, left, and right.

  4. The shortestPathAllKeys method initializes a queue (queue) to store the states to be explored, as well as variables for the grid dimensions (n and m), the starting position (start), sets for keys (keys) and locks (locks), and a variable to store a bit mask representing all the keys (allKeys).

  5. The method iterates over the grid to find the starting position, keys, and locks. The keys are added to the keys set, and the bit mask for all keys is updated accordingly. The locks are added to the locks set.

  6. The starting state is created with the starting position, zero steps, and no keys collected. It is added to the queue.

  7. The method calls the traverse method to explore the grid and find the shortest path. It passes the grid, queue, bit mask for all keys, set of keys, and set of locks.

  8. The traverse method initializes a 3-dimensional list (visited) to keep track of visited states. The dimensions of the list correspond to the grid dimensions and the number of possible key combinations.

  9. While the queue is not empty, the method dequeues a state from the front (node) and marks it as visited in the visited list.

  10. For each direction in the directions list, the method calculates the new position (newX and newY) based on the current position and direction.

  11. If the new position is within the grid boundaries and is not a wall ('#'), a new state (step) is created with the updated position and the same number of steps and keys as the current state.

  12. If the new position contains a key, the key is decoded and set in the step state by updating the keys variable using a bitwise OR operation.

  13. If the new position contains a lock, the lock is decoded and checked if the corresponding key is present in the step state. If not, the loop continues to the next iteration.

  14. If all keys have been collected (step.keys == allKeys), the method returns the number of steps taken in the step state.

  15. If the new position has not been visited with the same key combination, it is marked as visited, and the step state is added to the queue.

  16. If no path is

Complexities

The space complexity of this code is O(n * m * 2^k), where n and m are the dimensions of the grid and k is the number of keys. This is because the visited list has dimensions n * m * (2^k) to store the visited states. The queue can also have up to O(n * m * 2^k) states at its maximum size.

The time complexity of this code is O(n * m * 2^k), where n and m are the dimensions of the grid and k is the number of keys. This is because,

in the worst case, every cell in the grid can be visited with every possible key combination.

class State {
  final int x;
  final int y;
  final int steps;
  int keys;

  State(this.x, this.y, this.steps, this.keys);
}

class Solution {
  final List<dynamic> directions = [
    [0, -1],
    [0, 1],
    [1, 0],
    [-1, 0]
  ];

  int shortestPathAllKeys(List<String> grid) {
    final Queue<State> queue = Queue<State>();
    final int n = grid.length;
    final int m = grid[0].length;

    List<int> start = [0, 0];
    final Set<String> keys = Set<String>();
    final Set<String> locks = Set<String>();
    int allKeys = 0;

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        switch (grid[i][j]) {
          case '@':
            start = [i, j];
            break;
          case 'a':
          case 'b':
          case 'c':
          case 'd':
          case 'e':
          case 'f':
            keys.add(grid[i][j]);
            allKeys += 1 << (grid[i][j].codeUnitAt(0) - 'a'.codeUnitAt(0));
            break;
          case 'A':
          case 'B':
          case 'C':
          case 'D':
          case 'E':
          case 'F':
            locks.add(grid[i][j]);
            break;
        }
      }
    }

    queue.add(State(start[0], start[1], 0, 0));

    return traverse(grid, queue, allKeys, keys, locks);
  }

  int traverse(List<String> grid, Queue<State> queue, int allKeys,
      Set<String> keys, Set<String> locks) {
    final int n = grid.length;
    final int m = grid[0].length;
    final List<List<List<int>>> visited = List.generate(n, (_) {
      return List.generate(m, (_) {
        return List.generate(allKeys + 1, (_) => -1);
      });
    });

    while (queue.isNotEmpty) {
      final State node = queue.removeFirst();
      visited[node.x][node.y][node.keys] = node.steps;

      for (final List<int> dir in directions) {
        final int newX = (node.x + dir[0]);
        final int newY = node.y + dir[1];
        if (newX >= 0 &&
            newX < n &&
            newY >= 0 &&
            newY < m &&
            grid[newX][newY] != '#') {
          final step = State(newX, newY, node.steps + 1, node.keys);

          final s = grid[newX][newY];
          if (keys.contains(s)) {
            final decoded = 1 << (s.codeUnitAt(0) - 'a'.codeUnitAt(0));
            step.keys |= decoded;
          } else if (locks.contains(s)) {
            final decoded = 1 << (s.codeUnitAt(0) - 'A'.codeUnitAt(0));
            if ((step.keys & decoded) == 0) continue;
          }

          if (step.keys == allKeys) return step.steps;

          if (visited[newX][newY][step.keys] == -1) {
            visited[newX][newY][step.keys] = step.steps;
            queue.add(step);
          }
        }
      }
    }
    return -1;
  }
}