原题链接:https://leetcode.com/problems/word-ladder/
Description
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 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.
class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
if (beginWord == endWord) return 0;
unordered_set<string> vis;
size_t n = endWord.size();
typedef pair<string, int> PSI;
queue<PSI> q;
q.push(PSI(beginWord, 1));
vis.insert(beginWord);
while (!q.empty()) {
PSI t = q.front(); q.pop();
for (size_t i = 0; i < n; i++) {
string x = t.first;
for (int j = 0; j < 26; j++) {
x[i] = 'a' + j;
if (x == endWord) return t.second + 1;
if (wordList.find(x) != wordList.end() && vis.find(x) == vis.end()) {
q.push(PSI(x, t.second + 1));
vis.insert(x);
}
}
}
}
return 0;
}
};
双向广搜
class Solution {
using vec = vector<string>;
public:
int ladderLength(string start, string end, unordered_set<string>& dic) {
if(start == end) return 0;
alpha = vector<bool>(26, false);
for(auto &i: dic) { for(auto &j: i) alpha[j - 'a'] = true; }
int cur = 0, rcur = 0;
Q[cur].push_back(start);
rQ[rcur].push_back(end);
bfs.insert(start); rbfs.insert(end);
auto expandState = [&, this](vec &from, vec &to, unordered_set<string> &bfs) {
to.clear();
for(auto &r: from) {
for(int i = 0; i < (int)r.size(); i++) {
for(char j = 'a'; j <= 'z' ; j++) {
if(!alpha[j - 'a']) continue;
string temp = r;
temp[i] = j;
if(dic.find(temp) == dic.end() || bfs.find(temp) != bfs.end()) continue;
bfs.insert(temp);
to.push_back(temp);
}
}
}
};
for(int step = 1; step < 43 && !Q[cur].empty() && !rQ[rcur].empty(); step++) {
if(Q[cur].size() <= rQ[rcur].size()) {
expandState(Q[cur], Q[cur ^ 1], bfs);
cur ^= 1;
for(auto &r: Q[cur]) {
if(rbfs.find(r) != rbfs.end()) return step + 1;
}
} else {
expandState(rQ[rcur], rQ[rcur ^ 1], rbfs);
rcur ^= 1;
for(auto &r: rQ[rcur]) {
if(bfs.find(r) != bfs.end()) return step + 1;
}
}
}
return 0;
}
private:
vec Q[2], rQ[2];
vector<bool> alpha;
unordered_set<string> bfs, rbfs;
};