• LeetCode 127. Word Ladder 单词接龙(C++/Java)


    题目:

    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 beginWordis not a transformed word.

    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.

    Example 1:

    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.
    

    Example 2:

    Input:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log"]
    
    Output: 0
    
    Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

    分析:

    给定起始和终止两个单词,和一个单词列表,要求我们使用列表中的单词将起始和终止单词连接起来,连接的规则是要求每次只改变一个字符,且在列表中存在,终止单词也需要在列表中。

    我们可以利用广度优先搜索,从起始单词开始,将每一位字符从a到z依次改变,如果改变后的单词在列表中,就记录下来,并在集合中删去,这样做的目的是为了防止重复的搜索,例如dog-dop-dog,这样是浪费时间的,当新加入的单词和最终单词相同时,返回步骤数即可,如果保存搜索单词的集合(队列)为空时,证明已经搜索结束,且没有找到,返回0即可。

    还可以利用双向广度优先搜索进行优化,思想就是同时从起始单词和终止单词开始搜索,也是通过改变字符,且在单词列表中便加入到两个搜索集中,当一侧搜索出来的单词,在另一侧的搜索单词集中,意味着出现了解。至于搜索的次序,如果当一方的集合中的单词数量小于另一方时,就优先从数量小的集合开始搜索。

    程序:

    C++

    class Solution {
    public:
        int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
            //set<string> dict;
            unordered_set<string> dict;
            for(string s:wordList)
                dict.insert(s);
            if(dict.count(endWord) == 0)
                return 0;
            queue<string> q;
            q.push(beginWord);
            int l = beginWord.length();
            int step = 0;
            while(!q.empty()){
                step++;
                int len = q.size();
                for(int i = 0; i < len; ++i){
                    string word = q.front();
                    q.pop();
                    for(int j = 0; j < l; ++j){
                        char ch = word[j];
                        for(int k = 'a'; k <= 'z'; ++k){
                            if(k == ch)
                                continue;
                            word[j] = k;
                            if(word == endWord)
                                return step+1;
                            if(dict.count(word) == 0)
                                continue;
                            q.push(word);
                            dict.erase(word);
                        }
                        word[j] = ch;
                    }
                }
            }
            return 0;
        }
    };
    //Bidirectional BFS
    //Runtime: 28 ms, faster than 98.16% of C++ online submissions for Word Ladder.
    class Solution {
    public:
        int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
            //set<string> dict;
            unordered_set<string> dict;
            for(string s:wordList)
                dict.insert(s);
            if(dict.count(endWord) == 0)
                return 0;
            unordered_set<string> q1;
            unordered_set<string> q2;
            q1.insert(beginWord);
            q2.insert(endWord);
            int l = beginWord.length();
            int step = 0;
            while(!q1.empty() && !q2.empty()){
                step++;
                if(q1.size() > q2.size())
                    swap(q1, q2); 
                unordered_set<string> q;
                for(string word:q1){
                    for(int j = 0; j < l; ++j){
                        char ch = word[j];
                        for(int k = 'a'; k <= 'z'; ++k){
                            if(k == ch)
                                continue;
                            word[j] = k;
                            if(q2.count(word))
                                return step+1;
                            if(dict.count(word) == 0)
                                continue;
                            q.insert(word);
                            dict.erase(word);
                        }
                        word[j] = ch;
                    }
                }
                swap(q, q1);
            }
            return 0;
        }
    };

    Java

    class Solution {
        public int ladderLength(String beginWord, String endWord, List<String> wordList) {
            Set<String> dict = new HashSet<>(wordList);
            if(!dict.contains(endWord))
                return 0;
            Queue<String> q = new ArrayDeque<>();
            q.offer(beginWord);
            int l = beginWord.length();
            int step = 0;
            while(!q.isEmpty()){
                step++;
                int len = q.size();
                for(int i = 0; i < len; ++i){
                    //String word = q.poll();
                    StringBuilder word = new StringBuilder(q.poll());
                    for(int j = 0; j < l; ++j){
                        char ch = word.charAt(j);
                        for(int k = 'a'; k < 'z'; ++k){
                            if(ch == k)
                                continue;
                            word.setCharAt(j, (char)k);
                            String w = word.toString();
                            if(w.equals(endWord))
                                return step+1;
                            if(!dict.contains(w))
                                continue;
                            q.offer(w);
                            dict.remove(w);
                        }
                        word.setCharAt(j, ch);
                    }
                }
            }
            return 0;
        }
    }
    class Solution {
        public int ladderLength(String beginWord, String endWord, List<String> wordList) {
            Set<String> dict = new HashSet<>(wordList);
            if(!dict.contains(endWord))
                return 0;
            Set<String> q1 = new HashSet<>();
            q1.add(beginWord);
            Set<String> q2 = new HashSet<>();
            q2.add(endWord);
            int l = beginWord.length();
            int step = 0;
            while(!q1.isEmpty() && !q2.isEmpty()){
                step++;
                if(q1.size() > q2.size()){
                    Set<String> temp = q1;
                    q1 = q2;
                    q2 = temp;
                }
                Set<String> q = new HashSet<>();
                for(String s:q1){
                    StringBuilder str = new StringBuilder(s);
                    for(int i = 0; i < l; ++i){
                        char ch = str.charAt(i);
                        for(int j = 'a'; j <= 'z'; ++j){
                            if(ch == j)
                                continue;
                            str.setCharAt(i, (char)j);
                            String word = str.toString();
                            if (q2.contains(word)) 
                                return step + 1;
                            if(!dict.contains(word))
                                continue;
                            dict.remove(word);
                            q.add(word);
                        }
                        str.setCharAt(i, ch);
                    }
                }
                q1.clear();
                q1.addAll(q);
            }
            return 0;
        }
    }
  • 相关阅读:
    java这个404你能解决吗?
    java发邮件,这个坑你能填吗?
    自动评论csdn博客文章实现
    一款效率神器Ditto
    java加载国际化文件的几种姿势
    这个问题你能答对吗?
    mysql大小写敏感与校对规则
    java、golang日志文件转储压缩实现
    一款很好用的markdown编辑器
    beego与curl三件事
  • 原文地址:https://www.cnblogs.com/silentteller/p/12324111.html
Copyright © 2020-2023  润新知