赞
踩
今天常规刷题,刷到一道搜索的题目,第一次用单向BFS过了,然后发现耗时是大佬们的10倍,看了下网上的题解,大概学习了一下双向BFS。
双向BFS的特点是,从起点和终点同时出发,交替搜索,如果在中间相遇了,意味着终点和起点之间存在路径。双向BFS一般情况下可以大大减少搜索范围(脑补一下正方形从左上和右下启动,均按圆弧状往外搜索,一旦两个圆弧相交,搜索结束,那么左下角和右上角有大量区域不需要搜索)。能用双向BFS也是有限制的,起点和终点的位置必须是已知的,不然没法从两头开始启动搜索,比如从起点出发去找目标所在位置,这种搜索没法用双向BFS解决。
在实现BFS时,大概思路是:
1,先用起点和终点建立两个长度为一的集合set1和set2
2,进入循环
3,选择长度最短的集合进行更新(这样尽可能让每次计算量最小),一般操作是if len(set1) > len(set2): set1, set2 = set2, set1,然后一直都是更新set1。建立一个set3,为空,遍历set1,如果元素的子元素的vis为False,加入到set3,vis置为True; 如果为True,且在set2中(也就是另一端已经搜索到了),停止搜索,返回相应结果;如果都不是,就跳过
4,set1 = set3
5,回到2
补充一句:双向BFS还可以当成DFS的预处理,比如有些题目需要用DFS去把可行的路径全输出,可以先用双向BFS去判断这个方向可不可行在进行DFS搜索,当然,可不可行的状态要记得存,减少双向BFS的重复计算。
Leetcode127 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换过程中,每次只能改变单词的一个字母,且要保证改变后单词在给定的字典中。
题解:
- import numpy as np
- import collections
- import heapq
-
-
- class Solution(object):
- def ladderLength(self, beginWord, endWord, wordList):
- """
- :type beginWord: str
- :type endWord: str
- :type wordList: List[str]
- :rtype: int
- """
- Map = {}
- flag = {}
- wordSet = set(wordList)
- if endWord not in wordSet:
- return 0
- for item in wordSet:
- flag[item] = False
- Queue_1 = set()
- Queue_1.add(beginWord)
- Queue_2 = set()
- Queue_2.add(endWord)
- flag[endWord] = True
- ans = 2
- while len(Queue_1) != 0:
- if len(Queue_1) > len(Queue_2):
- Queue_1, Queue_2 = Queue_2, Queue_1
- next = []
- for item in Queue_1:
- for i in range(len(item)):
- for j in range(26):
- if item[i] == chr(ord('a')+j):
- continue
- word = item[0:i] + chr(ord('a')+j) + item[i+1:]
- if word in wordSet:
- if flag[word] == False:
- next.append(word)
- flag[word] = True
- elif word in Queue_2:
- return ans
- Queue_1 = set(next)
- ans += 1
- return 0

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。