127. Word Ladder

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.

解法1:236ms

class Solution {
public:
    /*每次把能到的单词加入队列,实质上就是一次bfs,相差一个字符用了hash处理*/
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        queue<string>q;
        set<string>s(wordList.begin(),wordList.end());
        s.insert(beginWord);
        addNext(beginWord, q, s);
        int length=2;
        while(!q.empty()){
            int size=q.size();//bfs一层的size
            for(int i=0;i<size;i++){
                beginWord=q.front();
                q.pop();
                if(beginWord==endWord){
                    return length;
                }
                addNext(beginWord,q,s);
            }
           length++; 
        }
        return 0;
    } 
    void addNext(string beginWord, queue<string>& q, set<string>& s){
        for(int i=0;i<beginWord.size();i++){
            char letter=beginWord[i];
            for(int j=0;j<26;j++){
                beginWord[i]='a'+j;
                if(s.find(beginWord)!=s.end()){
                    q.push(beginWord);
                    s.erase(beginWord);
                }
            }
            beginWord[i]=letter;
        }
    }
};

解法2:39ms

class Solution {
public:
    /*双端遍历,每次从size小的那层开始遍历,直到两层遍历到同一个节点时,说明找到了连接两个集合的桥*/
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string>word(wordList.begin(),wordList.end());
       // word.erase(endWord);
       // word.erase(beginWord);
       if(word.find(endWord)==word.end())return 0;
        unordered_set<string>next;
        unordered_set<string>prev;
        next.insert(beginWord);
        prev.insert(endWord);
        int ladder=2,len=beginWord.length();
        while(!next.empty()&&!prev.empty()){
            if(next.size()>prev.size())swap(next,prev);
            unordered_set<string>::iterator iter=next.begin();
            unordered_set<string>temp;
            for(;iter!=next.end();++iter){
                string str=*iter;
                for(int i=0;i<len;++i){
                    char letter=str[i];
                    for(int j=0;j<26;++j){
                        str[i]='a'+j;
                        if(prev.find(str)!=prev.end())
                            return ladder;
                        if(word.find(str)!=word.end()){
                            temp.insert(str);
                            word.erase(str);
                        }
                    }
                    str[i]=letter;
                }
            }
            ladder++;
            swap(temp,next);
        }
        return 0;
    } 
};

 

posted @ 2017-04-01 12:30  Tsunami_lj  阅读(134)  评论(0编辑  收藏  举报