1. 程式人生 > >Leetcode 126. Word Ladder II

Leetcode 126. Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return an empty list if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output:
[ ["hit","hot","dot","dog","cog"],   ["hit","hot","lot","log","cog"] ]

Example 2:

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Output: []

Explanation: The endWord "cog" is not in wordList, therefore no possibletransformation.

Answer:

two-end bfs.

兩個方向bfs,如果當前層和另一個方向的層有重疊,則找到路徑。bfs中儲存當前節點的父節點

from collections import defaultdict
class Solution(object):
    def findLadders(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: List[List[str]]
        """
        wordListset=set(wordList)
        if endWord not in wordListset:
            return []
        wl=len(beginWord)
        if wl==0:
            return []
        
        
        queue1=set()
        queue1.add(beginWord)
        queue2=set()
        queue2.add(endWord)
        parents= defaultdict(set)
        
        
        while queue1 and queue2:
            #print queue
            wordListset-=queue1
            nextqueue=set()
            for w in queue1:
                for i in range(wl):
                    for j in string.ascii_lowercase:
                        if j!=w[i]:
                            tempneww=w[0:i]+j+w[i+1:]
                            if tempneww in wordListset:
                                nextqueue.add(tempneww)
                                parents[tempneww].add(w)
            queue1=nextqueue
            if queue1 & queue2:
                result=[[endWord]]
                while result[0][0]!=beginWord:
                    result=[[p]+r for r in result for p in parents[r[0]]]
                return result
            
            wordListset-=queue2
            nextqueue=set()
            for w in queue2:
                for i in range(wl):
                    for j in string.ascii_lowercase:
                        if j!=w[i]:
                            tempneww=w[0:i]+j+w[i+1:]
                            if tempneww in wordListset:
                                nextqueue.add(tempneww)
                                parents[w].add(tempneww)
            queue2=nextqueue
            if queue1 & queue2:
                result=[[endWord]]
                while result[0][0]!=beginWord:
                    result=[[p]+r for r in result for p in parents[r[0]]]
                return result
            
        return []