美文网首页
Word Ladder

Word Ladder

作者: 瞬铭 | 来源:发表于2019-04-18 14:06 被阅读0次

一个单词字典,里面有一系列很相似的单词,然后给了一个起始单词和一个结束单词,每次变换只能改变一个单词,并且中间过程的单词都必须是单词字典中的单词,让我们求出最短的变化序列的长度。
https://leetcode.com/problems/word-ladder/

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

Output: 5

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

这题有个很明显的特征,就是需要考虑到26个字母组合的问题,用上面的例子说明,hit如何变化,
1.从第一个h开始变,可以有ait,bit,cit,dit......然后判断中间态的单词是否在wordList中,发现没有,再从第二个i开始变,发现hot中间态在wordList中,此时不要终止,得继续走完hia,hib,hic.....
2.对于hot重复上述操作,从第一个开始变,aot,bot,cot,dot.......发现dot在wordList,
3.重复1,2的过程中,如果刚好发现单词变成了cog,那我们的目的达到了

类似上述的变化,就像一个BFS,广度优先遍历的过程。hit,分别将三个单词找到所有的可能性,也就是它的下一层,再分别对下一层进行继续BFS,既然说到了BFS,那么就需要有一个队列,这个队列用来保存每一次的中间态,比如最开始只有hit,后来有了hot,后来有了dot......

**问题:如果不用a到z遍历,类似于hit单词在wordList里面找,发现有一个字母跟它不一样的,就暂存作为中间态。此时继续将这个中间态的单词再重复来,没试过这个方法

  • php
 /**
     * @param String $beginWord
     * @param String $endWord
     * @param String[] $wordList
     * @return Integer
     */
    function ladderLength($beginWord, $endWord, $wordList) {
        if (!in_array($endWord, $wordList)) {
            return 0;
        }
        $pathCnt = [
            $beginWord => 1,
        ];
        $queue   = new splqueue();
        $queue->enqueue($beginWord);
        while (!$queue->isEmpty()) {
            $word = $queue->dequeue();
            for ($i = 0; $i < strlen($word); $i++) {
                $newWord = $word;
                for ($ch = ord("a"); $ch <= ord("z"); $ch++) {
                    $str = chr($ch);
                    $newWord[$i] = $str;
                    if (in_array($newWord, $wordList) && $newWord == $endWord) {
                        return $pathCnt[$word] + 1;
                    }

                    if (in_array($newWord, $wordList) && !array_key_exists($newWord, $pathCnt)) {
                        $queue->push($newWord);
                        $pathCnt[$newWord] = $pathCnt[$word] + 1;
                    }
                }
            }
        }
        return 0;
    }
  • java 方法,对于过程,表格详细描述
1 word wordQueue level currnum nextnum set 说明
第一层,遍历第一个字母 hit [] 1 0 1 ["hot","dot","dog","lot","log","cog"] ait,bit.......zit发现hot在set中
第一层,遍历第二个字母 hit [hot] 1 0 1 ["dot","dog","lot","log","cog"] hat,hbt...hzt没有发现在set中
第一层,遍历第三个字母 hit [hot] 1 0 1 ["dot","dog","lot","log","cog"] hia,hib,hic...hiz没有发现在set中
第二层,遍历第一个字母 hot [] 2 0 0 ["dot","dog","lot","log","cog"] aot,bot...zot,发现dot在set中
第二层,遍历第一个字母 hot [dot] 2 0 1 ["dog","lot","log","cog"] aot,bot...zot,发现lot在set中
第二层,遍历第二个字母 hot [dot,lot] 2 0 2 ["dog","log","cog"] hat...hzt,没有发现在set中
第二层,遍历第三个字母 hot [dot,lot] 2 0 2 ["dog","log","cog"] haa,hab...haz,没有发现在set中
第三层,遍历第一个字母 dot [lot] 3 1 0 ["dog","log","cog"] aot,bot...zot没有发现在set中
第三层,遍历第二个字母 dot [lot] 3 1 0 ["dog","log","cog"] dat,dbt...dzt没有发现在set中
第三层,遍历第三个字母 dot [lot] 3 1 0 ["dog","log","cog"] doa,dob...doz,发现dog在set中
第三层,遍历第一个字母 lot [dog] 3 0 1 ["log","cog"] aot,abt..azt,没发现
第三层,遍历第二个字母 lot [dog] 3 0 1 ["log","cog"] lat,lbt..lzt,没发现
第三层,遍历第三个字母 lot [dog] 3 0 2 ["log","cog"] loa,lob..loz,发现log
第四层,遍历第一个字母 dog [log] 4 2 0 ["cog"] aog,bog...zog,没发现
第四层,遍历第二个字母 dog [log] 4 2 0 ["cog"] dag,dbg...dzg,没发现
第四层,遍历第三个字母 dog [log] 4 2 0 ["cog"] doa,dob...doz,没发现
第四层,遍历第三个字母 dog [log] 4 2 0 ["cog"] doa,dob...doz,没发现
第四层,遍历第一个字母 log [] 5 1 0 ["cog"] aog...zog,发现cog,且cog==endWord,return level+1
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        HashSet<String> set = new HashSet<>(wordList);
        Queue<String> wordQueue = new LinkedList<String>();
        int level = 1;//最开始的string  就是level 为1 了
        int currnum = 1;//当前level有多少个单词
        int nextnum = 0;//下一个level的计数器
        wordQueue.add(beginWord);
        while (!wordQueue.isEmpty()) {
            String word = wordQueue.poll();
            currnum--;
            for (int i = 0; i < word.length(); i++) {
                char[] wordunit = word.toCharArray();
                for (char j = 'a'; j <= 'z'; j++) {
                    wordunit[i] = j;
                    String temp = new String(wordunit);

                    if (set.contains(temp)) {
                        if (temp.equals(endWord)) {
                            return level + 1;
                        }

                        nextnum++;
                        wordQueue.add(temp);
                        set.remove(temp);
                    }
                }
            }

            if (currnum == 0) {
                currnum = nextnum;
                nextnum = 0;
                level++;
            }
        }
        return 0;
    }
  • 一种较为简洁的解法,原理还是BFS
 public int ladderLength3(String beginWord, String endWord, List<String> wordList) {
        HashSet<String> set = new HashSet<String>(wordList);
        Queue<String> queue = new LinkedList<String>();
        queue.offer(beginWord);
        int res = 0;
        while (!queue.isEmpty()) {

            // 一层一层来
            for (int k = queue.size(); k > 0; k--) {
                String word = queue.poll();
                if (word.equals(endWord)) {
                    return res + 1;
                }
                for (int i = 0; i < word.length(); i++) {
                    char[] charArray = word.toCharArray();
                    for (char ch = 'a'; ch <= 'z'; ch++) {

                        charArray[i] = ch;
                        String newString = new String(charArray);
                        // 变化后的word在set中,但是还未到终点
                        if (set.contains(newString) && newString != word) {
                            queue.offer(newString);
                            set.remove(newString);
                        }
                    }
                }
            }
            res++;
        }
        return 0;
    }

相关文章

网友评论

      本文标题:Word Ladder

      本文链接:https://www.haomeiwen.com/subject/ocezwqtx.html