[LeetCode]126. Word Ladder II
126. Word Ladder II
回朔
class Solution(object):
    def findLadders(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: List[List[str]]
        """
        def backtracking(cur, path):
            if cur == endWord:
                if not res:
                    res.append(list(path))
                elif len(path) < len(max(res, key=lambda x:len(x))):
                    del res[:]
                    res.append(list(path))
                elif len(path) == len(max(res, key=lambda x:len(x))):
                    res.append(list(path))
                return
            for i in range(len(beginWord)):
                for j in range(26):
                    char = chr(ord('a') + j)
                    new_word = cur[:i] + char + cur[i + 1:]
                    if new_word in wordList and new_word not in visited:
                        path.append(new_word)
                        visited.add(new_word)
                        backtracking(new_word, path)
                        path.pop()
                        visited.remove(new_word)
        res = []
        visited = {beginWord, }
        backtracking(beginWord, [beginWord,])
        return res
Two BFS(图论)
import collections
class Solution(object):
    # Solution using double BFS
    def findLadders(self, begin, end, words_list):
        # 生成路径
        def construct_paths(source, dest, tree):
            if source == dest:
                return [[source]]
            return [[source] + path for succ in tree[source]
                    for path in construct_paths(succ, dest, tree)]
        # 添加路径,形成一个图
        def add_path(tree, word, neigh, is_forw):
            # 保证不会重复加入字符串,造成双方均可到达的情况
            if is_forw:
                tree[word] += neigh,
            else:
                tree[neigh] += word,
        # start_set是从起始字符串开始进行搜索,end_set是从终止字符串开始搜索
        def two_bfs(start_set, end_set, tree, is_forw, words_set):
            if not start_set: return False
            # 保证start_set长度最小
            if len(start_set) > len(end_set):
                return two_bfs(end_set, start_set, tree, not is_forw, words_set)
            # 删除访问过的结点
            for word in (start_set | end_set):
                words_set.discard(word)
            next_set, done = set(), False
            while start_set:
                word = start_set.pop()
                for c in set('abcdefghijklmnopqrstuvwxyz'):
                    for index in range(len(word)):
                        neigh = word[:index] + c + word[index + 1:]
                        # 如果字符串存在于end中,说明end已经访问过,那么此时构成一条路径
                        if neigh in end_set:
                            done = True
                            add_path(tree, word, neigh, is_forw)
                        # 如果该字符串都没有被访问过,也加入到路径中
                        if not done and neigh in words_set:
                            next_set.add(neigh)
                            add_path(tree, word, neigh, is_forw)
            return done or two_bfs(next_set, end_set, tree, is_forw, words_set)
        tree, path = collections.defaultdict(list), [begin]
        two_bfs({begin}, {end}, tree, True, set(words_list))
        return construct_paths(begin, end, tree) 
关注公众号:数据结构与算法那些事儿,每天一篇数据结构与算法
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号