zoukankan      html  css  js  c++  java
  • 127. Word Ladder

    https://leetcode.com/problems/word-ladder/#/description

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence 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"]

    As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
    return its length 5.

    Note:

    • Return 0 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.

    Sol :

    from collections import deque
    
    class Solution(object):
        def ladderLength(self, beginWord, endWord, wordList):
            """
            :type beginWord: str
            :type endWord: str
            :type wordList: List[str]
            :rtype: int
            """
            
            # Time O(n) Space O(n)
            
            # Suppose that we have a huge number of buckets, each of them with a four-letter word on the outside, except that one of the letters in the label has been replaced by an underscore.
            # See Figure 1 
            # We can implement the scheme we have just described by using a dictionary. 
            # The labels on the buckets we have just described are the keys in our dictionary. 
            # The value stored for that key is a list of words. 
            
            def construct_dict(word_list):
                d = {}
                for word in word_list:
                    for char in range(len(word)):
                        # s is the label of buckets, i,e, key of the dictionary
                        s = word[:char] + "_" + word[char+1:]
                        # d[s] is the content of busckets, list of words. i.e. value of the dictinoary.
                        d[s] = d.get(s, []) + [word]
                # after the outer for loop, d is like:
                # e.x. d[_ope] = ["pope", "rope", "lope"]
                # d[p_pe] = ["pope", 'pipe']
                # ... 
                
                return d
            
            
                
            # the input dict_words is in the format of the ouput if previous method
            # e.x. dict_words[_ope] = ["pope", "rope", "lope"]
            # dict_words[p_pe] = ["pope", 'pipe']
            # ... 
            # the reason why the input dictinoary is in the "buscket" format is to save time... btw, tried the "non buscket " way, time exceeds limit...
            
            
            def bfs_words(begin, end, dict_words):
                queue, visited = deque([(begin, 1)]), set()
                # the queue stores the final path 
                while queue:
                    # initiate word and steps; restore queue to empty when first come in
                    # advance to examining the word just added to the queue in second and the following while loops
                    word, steps = queue.popleft()
                    if word not in visited:
                        visited.add(word)
                        if word == end:
                            return steps
                        for i in range(len(word)):
                            s = word[:i] + "_" + word[i+1:]
                            neigh_words = dict_words.get(s, [])
                            for neigh in neigh_words:
                                if neigh not in visited:
                                    queue.append((neigh, steps + 1))
                return 0
            
            d = construct_dict(wordList)
            return bfs_words(beginWord, endWord, d)

    Similar to :

  • 相关阅读:
    @FeignClient同一个name使用多个配置类报错,解决方案【转+改进】
    spring cloud 与spring boot 版本不匹配引发的问题总结
    无聊系列
    基于redis+lua实现的分布式限流
    elasticsearch 优化笔记
    redis+lua库存扣减和冲正
    es-dsl笔记
    wiki—-Confluence搭建
    Linux常用命令
    SQLSERVER|CDC 日志变更捕获机制
  • 原文地址:https://www.cnblogs.com/prmlab/p/7156444.html
Copyright © 2011-2022 走看看