BFS
宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
用法
- BFS,其英文全称是Breadth First Search。 BFS并不使用经验法则算法。从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。
- 优化:广度搜索的判断重复如果直接判断十分耗时,我们一般借助哈希表来优化时间复杂度。
- DFS的复杂度与BFS的复杂度大体一致,不同之处在于遍历的方式与对于问题的解决出发点不同,DFS适合目标明确,而BFS适合大范围的寻找。
相关题目
127. 单词接龙
题目:给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
- 分析:其实就是将beginWord 单词作为树的根节点,依次向下遍历,看这棵树的叶子结点有没有endWord (有时候也不一定是叶子结点)。如果存在,返回其深度depth,反之返回0。此处有一点需要
- 注意::在树上层出现过的字符串没必要在下层再次出现,因为如果该字符串是转换过程中必须经过的中间字符串,那么应该挑选上层的该字符串继续进行变化,它的转换次数少。
- 常规超时:
- 我们在单词匹配是否只差一个字母的时候用了太多的计算时间, dog, cog,只有中间一位不同,我们可以建立一个字典,其中 *og可以表示后两位位og的三位单词,这样做的话,以来就建立了一个字典,如果右只差一位的单词,就会被聚合到一个字典的键值下面。在进行BFS查找匹配的时候,我们的效率会加快很多
- 还有一种方法就是双向BFS,不止是单向从 begin 到 end, 我们也从 end 查找 begin,这个方法但是我现在还没仔细看,等下次回过头再看。
- 解题模板:
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
# BFS
from collections import deque, defaultdict
# 先验判断
if endWord not in wordList:
return 0
# 提前构建邻接表 -> 用generic state做key
intermidiateWords = defaultdict(list)
wordLen = len(beginWord)
for word in wordList:
for i in range(wordLen):
intermidiateWords[word[:i] + '*' + word[i+1:]].append(word)
# 建队列 加初始状态
queue = deque()
memo = set()
queue.append(beginWord)
memo.add(beginWord)
step = 1
while queue:
size = len(queue)
for _ in range(size):
curWord = queue.popleft()
for i in range(wordLen):
intermidiateCurWord = curWord[:i] + '*' + curWord[i+1:]
# 下一个状态的所有word
for word in intermidiateWords[intermidiateCurWord]:
if word == endWord:
return step + 1
if word not in memo:
queue.append(word)
memo.add(word)
step += 1
else:
return 0
301. 删除无效的括号
题目:删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。说明: 输入可能包含了除 ( 和 ) 以外的字符。
- 分析首先建立一个判断是否括号合法的函数,可以使用计数也可以使用栈。
- 首先加入s到字符串集合中判断当前的集合内的字符串是否有合法的,如果有就提前返回
- 如果没有就要考虑删除字符串的的一些括号,我们每一层的删除之后就传递给下一层,如果下一层还是没有合法的,就继续上一层的删除后的字符串继续删除。
- 总的来说就是每一层对集合内的字符串,每一个字符串选择一个括号删除,所以一个字符串内有多少个括号,一个字符串就有多少个删除可能性,把每一个字符串的删除可能性加入到下一层的集合内部,放到下一层进行判断。
- 解题模板:
class Solution:
def removeInvalidParentheses(self, s: