Word Ladder

来源:互联网 发布:淘宝客服要做什么 编辑:程序博客网 时间:2024/06/04 18:56

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 intermediate word must exist in the word list

For example,

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

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.
  • class Solution {public:   int countStep(const string& s1, const string& s2)    {        int len1 = s1.size();        // int len2 = s2.size();        // if(len1 != len2)        // {        //     return 0;        // }        int i;        int step = 0;        for(i = 0; i < len1; ++i)        {            if(s1[i] != s2[i])            {                ++step;                if(step >= 2)                {                    return step;                }            }        }        return step;    }    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList)    {        unordered_set<string>::iterator it = wordList.begin();        unordered_set<string> del;        queue<string> Q1;        queue<string> Q2;        int count = 0;        if(beginWord == endWord)        {            return count;        }        for(; it != wordList.end(); ++it)        {            if(countStep(*it, beginWord) == 1)            {                Q1.push(*it);                //itmp                //wordList.erase(*it);                            }else            {                del.insert(*it);            }        }        ++count;        wordList.clear();        while(1)        {            while(!Q1.empty())            {                if(countStep(Q1.front(), endWord) == 0)                {                    //++count;                    return count;                }else if(countStep(Q1.front(), endWord) == 1)                {                    ++count;                    return count;                }else                {                    for(it = del.begin(); it != del.end(); ++it)                    {                        if(countStep(*it, Q1.front()) == 1)                        {                            Q2.push(*it);                        }else                        {                            wordList.insert(*it);                        }                    }                    //wordList.erase(Q1.front());                                        Q1.pop();                }            }            del.clear();            if(wordList.size() == 0)            {                return 0;            }            if(Q1.empty() && Q2.empty())            {                return 0;                //break;            }            ++count;            while(!Q2.empty())            {                if(countStep(Q2.front(), endWord) == 0)                {                    //++count;                    return count;                }else if(countStep(Q2.front(), endWord) == 1)                {                    ++count;                    return count;                }else                {                    for(it = wordList.begin(); it != wordList.end(); ++it)                    {                        if(countStep(*it, Q2.front()) == 1)                        {                            Q1.push(*it);                        }else                        {                            del.insert(*it);                        }                    }                    //wordList.erase(Q2.front());                                       Q2.pop();                }                            }            wordList.clear();            if(del.size() == 0)            {                return 0;            }            if(Q1.empty() && Q2.empty())            {                return 0;                //break;            }            ++count;        }         return count;                }};
    上面这段代码一直超时,原因在于 构造图的每一层时的时间复杂度是 n^2级别
  • 这里我们可以不用实际构造图,而在BFS遍历的时候去寻找当前单词可达的下一个单词。如果还是通过遍历所有的单词判断是否可达,则复杂度和上面一样,但实际上在上千个单词中,只有少数几个可以由当前单词一步到达,我们之前的比较浪费了很多时间在不可能的单词上。网上对该问题的解决无一例外都是按照下面的思路:将当前单词每一个字符替换成a~z的任意一个字符,然后判断是否在词典中出现。此时的复杂度是O(26*word_length),当单词比较短时,这种方法的优势就体现出来了。
  • class Solution {public:    int ladderLength(string start, string end, unordered_set<string> &dict) {        // IMPORTANT: Please reset any member data you declared, as        // the same Solution instance will be reused for each test case.        //BFS遍历找到的第一个匹配就是最短转换,空字符串是层与层之间的分隔标志        queue<string> Q;        Q.push(start); Q.push("");        int res = 1;        while(Q.empty() == false)        {            string str = Q.front();            Q.pop();            if(str != "")            {                int strLen = str.length();                for(int i = 0; i < strLen; i++)                {                    char tmp = str[i];                    for(char c = 'a'; c <= 'z'; c++)                    {                        if(c == tmp)continue;                        str[i] = c;                        if(str == end)return res+1;                        if(dict.find(str) != dict.end())                        {                            Q.push(str);                            dict.erase(str);                        }                    }                    str[i] = tmp;                }            }            else if(Q.empty() == false)            {//到达当前层的结尾,并且不是最后一层的结尾                res++;                Q.push("");            }        }        return 0;    }};



0 0
原创粉丝点击