000864-Shortest-Path-to-Get-All-Keys
Last updated
class Solution:
def shortestPathAllKeys(self, grid: List[str]) -> int:
rows, cols = len(grid), len(grid[0])
# find start pos and number of keys
start_r, start_c, keys = 0, 0, 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == '@':
start_r, start_c = r, c
elif grid[r][c].islower():
keys += 1
# BFS
queue = deque()
queue.append((start_r, start_c, 0))
visited = set()
visited.add((start_r, start_c, 0))
steps = 0
while queue:
size = len(queue)
for _ in range(size):
r, c, key = queue.popleft()
if grid[r][c].islower():
key |= 1 << (ord(grid[r][c]) - ord('a'))
if key == (1 << keys) - 1:
return steps
# scan 4 directions
for nr, nc in [(r+1, c), (r-1, c), (r, c+1), (r, c-1)]:
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] != '#':
if grid[nr][nc].isupper() and key & (1 << (ord(grid[nr][nc]) - ord('A'))) == 0:
continue
if (nr, nc, key) not in visited:
visited.add((nr, nc, key))
queue.append((nr, nc, key))
steps += 1
return -1 # not found