在BFS階段,遍歷startSet裏面的每一個word,先看endSet裏有沒有next Level的單詞,如果有,則找到一條最短路徑,直接返回。否則,再在unusedSet裏面找next Level的節點,如果有,加入nextSet,並且從unusedWords中刪除
// 860 ms
class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
int bLen = beginWord.length();
int eLen = endWord.length();
int size = wordDict.size();
if (bLen != eLen || bLen == 0 || size == 0) return 0;
unordered_set<string> unusedWords = wordDict; // words that never visited before
unordered_set<string> activeWords[3];
int startSet = 0;
int endSet = 1;
int nextSet = 2;
int depth = 2;
activeWords[startSet].insert(beginWord);
activeWords[endSet].insert(endWord);
unusedWords.erase(beginWord);
unusedWords.erase(endWord);
while(!activeWords[startSet].empty()){
for (auto it : activeWords[startSet]){
for (auto itend : activeWords[endSet]){
if (match(it, itend)){
return depth;
}
}
vector<string> temp;
for (auto itun : unusedWords){
if (match(it, itun)){
activeWords[nextSet].insert(itun);
temp.push_back(itun);
//這裏不能直接用下面這句,因爲你迭代器是 unusedWords的,把它的元素刪除,迭代器就被玩壞了
//unusedWords.erase(itun);
}
}
for (auto istr : temp){
unusedWords.erase(istr);
}
}
depth++;
swap(startSet, nextSet);
if (activeWords[startSet].size() > activeWords[endSet].size()) {
swap(startSet, endSet);
}
activeWords[nextSet].clear();
}
return 0;
}
bool match(string wordA, string wordB){
if (wordA.length() != wordB.length()) return false;
int diff = 0;
for (int i = 0; i < wordA.length(); ++i){
if (wordA[i] == wordB[i]) continue;
diff++;
if (diff > 1){
return false;
}
}
if (diff == 1) return true;
return false;
}
};
for (auto it : activeWords[startSet]){
char temp, i;
for(int i = 0; i < it.length(); ++i){
temp = it[i];
for(char j = 'a'; j < 'z'; ++j){
if (temp == j) continue;
it[i] = j;
if (activeWords[endSet].count(it) > 0){
return depth;
}else if (unusedWords.count(it) > 0){
activeWords[nextSet].insert(it);
unusedWords.erase(it);
}
}
it[i] = temp;
}
}