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:
- Only one letter can be changed at a time.
- 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; } };