@@ -110,6 +110,75 @@ class Solution:
110110 flip += 1
111111```
112112
113+ ## Bidrectional BFS
114+
115+ 当求点对点的最短路径时,BFS遍历结点数目随路径长度呈指数增长,为缩小遍历结点数目可以考虑从起点 BFS 的同时从终点也做 BFS,当路径相遇时得到最短路径。
116+
117+ ### [ word-ladder] ( https://leetcode-cn.com/problems/word-ladder/ )
118+
119+ ``` Python
120+ class Solution :
121+ def ladderLength (self , beginWord : str , endWord : str , wordList : List[str ]) -> int :
122+
123+ N, K = len (wordList), len (beginWord)
124+
125+ find_end = False
126+ for i in range (N):
127+ if wordList[i] == endWord:
128+ find_end = True
129+ break
130+
131+ if not find_end:
132+ return 0
133+
134+ wordList.append(beginWord)
135+ N += 1
136+
137+ # clustering nodes for efficiency compare to adjacent list
138+ cluster = collections.defaultdict(list )
139+ for i in range (N):
140+ node = wordList[i]
141+ for j in range (K):
142+ cluster[node[:j] + ' *' + node[j + 1 :]].append(node)
143+
144+ # bidirectional BFS
145+ visited_start, visited_end = set ([beginWord]), set ([endWord])
146+ bfs_start, bfs_end = collections.deque([beginWord]), collections.deque([endWord])
147+ step = 2
148+ while bfs_start and bfs_end:
149+
150+ # start
151+ num_level = len (bfs_start)
152+ while num_level > 0 :
153+ node = bfs_start.popleft()
154+ for j in range (K):
155+ key = node[:j] + ' *' + node[j + 1 :]
156+ for n in cluster[key]:
157+ if n in visited_end: # if meet, route from start larger by 1 than route from end
158+ return step * 2 - 2
159+ if n not in visited_start:
160+ visited_start.add(n)
161+ bfs_start.append(n)
162+ num_level -= 1
163+
164+ # end
165+ num_level = len (bfs_end)
166+ while num_level > 0 :
167+ node = bfs_end.popleft()
168+ for j in range (K):
169+ key = node[:j] + ' *' + node[j + 1 :]
170+ for n in cluster[key]:
171+ if n in visited_start: # if meet, route from start equals route from end
172+ return step * 2 - 1
173+ if n not in visited_end:
174+ visited_end.add(n)
175+ bfs_end.append(n)
176+ num_level -= 1
177+ step += 1
178+
179+ return 0
180+ ```
181+
113182## Dijkstra's Algorithm
114183
115184用于求解单源最短路径问题。思想是 greedy 构造 shortest path tree (SPT),每次将当前距离源点最短的不在 SPT 中的结点加入SPT,与构造最小生成树 (MST) 的 Prim's algorithm 非常相似。可以用 priority queue (heap) 实现。
@@ -178,7 +247,7 @@ class Solution:
178247 return - 1
179248```
180249
181- ## A* Algorithm
250+ ## 补充: A* Algorithm
182251
183252当需要求解有目标的最短路径问题时,BFS 或 Dijkstra's algorithm 可能会搜索过多冗余的其他目标从而降低搜索效率,此时可以考虑使用 A* algorithm。原理不展开,有兴趣可以自行搜索。实现上和 Dijkstra’s algorithm 非常相似,只是优先级需要加上一个到目标点距离的估值,这个估值严格小于等于真正的最短距离时保证得到最优解。当 A* algorithm 中的距离估值为 0 时 退化为 BFS 或 Dijkstra’s algorithm。
184253
0 commit comments