@@ -110,6 +110,75 @@ class Solution:
110
110
flip += 1
111
111
```
112
112
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
+
113
182
## Dijkstra's Algorithm
114
183
115
184
用于求解单源最短路径问题。思想是 greedy 构造 shortest path tree (SPT),每次将当前距离源点最短的不在 SPT 中的结点加入SPT,与构造最小生成树 (MST) 的 Prim's algorithm 非常相似。可以用 priority queue (heap) 实现。
@@ -178,7 +247,7 @@ class Solution:
178
247
return - 1
179
248
```
180
249
181
- ## A* Algorithm
250
+ ## 补充: A* Algorithm
182
251
183
252
当需要求解有目标的最短路径问题时,BFS 或 Dijkstra's algorithm 可能会搜索过多冗余的其他目标从而降低搜索效率,此时可以考虑使用 A* algorithm。原理不展开,有兴趣可以自行搜索。实现上和 Dijkstra’s algorithm 非常相似,只是优先级需要加上一个到目标点距离的估值,这个估值严格小于等于真正的最短距离时保证得到最优解。当 A* algorithm 中的距离估值为 0 时 退化为 BFS 或 Dijkstra’s algorithm。
184
253
0 commit comments