【LeetCode】126. Word Ladder II【H】

175 篇文章 0 订阅
157 篇文章 0 订阅

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.

For example,

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

Return

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

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.

UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

Subscribe to see which companies asked this question.




广搜。

最开始的做法,也就是被注释掉的那个,是最平白直叙的方式做的,39个case,过了23个。

结果是超时了。是因为,用了set保存了当前的全部路径,这个开销还是很大的。

然后看了别人的做法,不应该保存整个路径,只保存每个节点的父节点就行了,这样会省下好多空间


class Solution(object):
    def findLadders(self, beginWord, endWord, wordList):
        
        
        '''
        
        def check(s1,s2):
            if abs(len(set(s1)) - len(set(s2))) > 1:
                return False
            count = 0
            #print s1,s2,
            for i in xrange(len(s1)):
                if s1[i] != s2[i]:
                    count += 1
            #print count
            return count == 1
        
        b = beginWord
        e = endWord
        l = wordList
        
        res = []
        
        cur = (b,)
        res = [cur]
        v = set()
        
        
        count = 0
        '''        '''
        flag = 1
        while flag:
            count += 1
            tres = res[:]
            res = []
            for cur in tres:
                for i in l:
                    if i not in cur and cur + (i,) not in v and check(cur[-1],i):
                        #print cur + (i,)
                        res += cur + (i,),
            #print len(res)
            if res == []:
                return []
            tres = []
            for i in res:
                #print i,i[-1],e
                if len(i) > len(l):
                    return []
                if i[-1] == e:
                    flag = 0
                    tres += list(i),
        return tres
            
        '''
        
        
    #def findLadders(self, start, end, dic):
        start = beginWord
        end = endWord
        dic = set(wordList)
        
        #dic.add(end)
        level = {start}
        # 记录父节点是谁
        parents = collections.defaultdict(set)
        while level and end not in parents:
            next_level = collections.defaultdict(set)
            #对每一层进行遍历
            for node in level:
                #根据字母来进行遍历
                for char in string.ascii_lowercase:
                    #分别放进每个位置里
                    for i in range(len(start)):
                        n = node[:i]+char+node[i+1:]
                        # 如果n在字典里,并且n目前还不是前驱
                        if n in dic and n not in parents:
                            next_level[n].add(node)
                            
            print level
            print parents
            print next_level
            print ''
            
            level = next_level
            parents.update(next_level)
        res = [[end]]
        print parents
        while res and res[0][0] != start:
            res = [[p]+r for r in res for p in parents[r[0]]]
        return res
        
        
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: List[List[str]]
        """
        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值