Leetcode OJ 127 Word Ladder [Medium]

来源:互联网 发布:java 日志服务器搭建 编辑:程序博客网 时间:2024/06/03 12:32

Leetcode OJ 127 Word Ladder  

题目描述:

Given two words (beginWord and endWord), and adictionary's word list, find the length of shortest transformation sequencefrom beginWord to endWord, such that:

Only one letter can be changed at a time.

Each transformed word must exist in the word list. Notethat 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 andare not the same.

题目理解:

给定单词beginWord 和 endWord,和一个单词集合wordList,找到从beginWord到endWord变换的最短的序列。没变换只能变换一个字母;每个变换的单词必须在所给单词集合wordList中。

如果没有变换序列则返回0;

所有的单词有相同的长度;

所有的单词都是小写字母;

可以假定单词集合wordList中没有重复的单词。

可以假定beginWord和endWord是非空且不同。

测试用例:

功能测试:不存在没有变换序列;存在变换序列有长度不同的路径;

特殊输入:单词序列中只有一个endWord;

解答(参考代码):

1.  设置两个集合,reached代表已访问的单词(当前步的单词),wordDict代表未访问的单词;

2.  当reached中不包含endWord时进行以下循环:

3.  遍历reached集合,对每一个reached中的单词,给出所有可能的转换,并判断转换是否包含于wordDict,如果包含于,则将该转换添加到toAdd集合中,toAdd集合是下一次循环的reached集合,并将转换单词从wordDict中移除;

4.  遍历完reached集合后,距离distance加1;

5.  并判断reached的集合大小,如果reached大小是0,则说明到目前为止没有转换单词,即转换序列中断,也就是没有符合要求的转换序列,则返回0;

6.  将toAdd赋值给reached,代表下一步的单词集合;

7.  当最外层循环循环结束后,返回distance;

ps: I get TLE at the first two submissions, because when Icheck if wordDict has any matches with reached set, I use two for loops anddetermine if any pair of words differ by one. That's a huge slow-down becauseit'll takes m (size of reached) * n (size of wordDict) * l (length of words) time,while in this solution, it takes 26 * l * m time. So when n is huge, thissolution will be (n/26) times faster.

public int ladderLength(String beginWord, String endWord, Set<String> wordDict) {    Set<String> reached = new HashSet<String>();    reached.add(beginWord);    wordDict.add(endWord);    int distance = 1;    while (!reached.contains(endWord)) {        Set<String> toAdd = new HashSet<String>();        for (String each : reached) {            for (int i = 0; i < each.length(); i++) {                char[] chars = each.toCharArray();                for (char ch = 'a'; ch <= 'z'; ch++) {                    chars[i] = ch;                    String word = new String(chars);                    if (wordDict.contains(word)) {                        toAdd.add(word);                        wordDict.remove(word);                    }                }            }        }        distance++;        if (toAdd.size() == 0) return 0;        reached = toAdd;    }    return distance;}

其他解答(参考代码):

1.  It'smuch faster than one-end search indeed as explained in wiki.

2.  BFSisn't equivalent to Queue. Sometimes Set is more accurate representation fornodes of level. (also handy since we need to check if we meet from two ends)

3.  It'ssafe to share a visited set for both ends since if they meet same string itterminates early. (vis is useful since we cannot remove word from dict due to bidirectionalsearch)

4.  It seemslike if(set.add()) is a little slower than if(!contains()) then add() but it'smore concise.

public int ladderLength(String beginWord, StringendWord, Set<String> wordList) {    int pathLength= 2;    Set<String> start = new HashSet<>();    Set<String> end = new HashSet<>();    start.add(beginWord);    end.add(endWord);    wordList.remove(beginWord);    wordList.remove(endWord);    while (!start.isEmpty()){        if (start.size()> end.size()) {            Set<String> temp =start;            start = end;            end = temp;        }        Set<String> next = new HashSet<>();        for (Stringcur : start) {            char[]strArray = cur.toCharArray();            for (int i = 0; i < strArray.length; i++){                char old = strArray[i];                for (char c = 'a'; c<= 'z'; c++) {                    strArray[i] = c;                    String str = String.valueOf(strArray);                    if (end.contains(str)) {                        return pathLength;                    }                    if (wordList.contains(str)) {                        next.add(str);                       wordList.remove(str);                    }                }                strArray[i] = old;            }        }        start = next;        pathLength++;    }    return 0;} 


原创粉丝点击