BFS Shortest Path Template - cocoder39/coco39_LC GitHub Wiki
BFS is specifically useful for finding the shortest path in unweighted graphs where all edges have the same weight (implicitly 1)
- Time Complexity: 𝑂(𝑉+𝐸) where 𝑉 is the number of vertices and E is the number of edges. This is because each node and each edge is processed once.
- Space Complexity: 𝑂(𝑉) , as it uses additional space for the queue, distance, and predecessor tracking.
Option 1: first discovered path to a node is always the shortest. This is guaranteed by the nature of BFS in unweighted graphs.
from collections import deque
def bfs_shortest_path_infinity_check(graph, start, target):
queue = deque([start])
distances = {node: float('inf') for node in graph}
distances[start] = 0
predecessors = {node: None for node in graph}
while queue:
current = queue.popleft()
for neighbor in graph[current]:
if distances[neighbor] == float('inf'): # Only check if distance is infinity
distances[neighbor] = distances[current] + 1
predecessors[neighbor] = current
queue.append(neighbor)
# Reconstruct path
path = []
current = target
while current is not None:
path.append(current)
current = predecessors[current]
path.reverse()
return path if distances[target] != float('inf') else None
# Example usage:
print(bfs_shortest_path_infinity_check(graph, 'A', 'F')) # Expected output: ['A', 'C', 'D', 'F']
Option 2: a more general way to get shortest path is to update only if a shorter path is found.
from collections import deque
def bfs_shortest_path(graph, start, target):
queue = deque([start])
distances = {node: float('inf') for node in graph}
distances[start] = 0
predecessors = {node: None for node in graph}
while queue:
current = queue.popleft()
for neighbor in graph[current]:
new_distance = distances[current] + 1
if new_distance < distances[neighbor]: # Update if a shorter path is found
distances[neighbor] = new_distance
predecessors[neighbor] = current
queue.append(neighbor)
# Reconstruct path
path = []
current = target
while current is not None:
path.append(current)
current = predecessors[current]
path.reverse()
return path if distances[target] != float('inf') else None
# Example usage:
print(bfs_shortest_path(graph, 'A', 'F')) # Expected output: ['A', 'C', 'D', 'F']