此题与word ladder相比,求解相邻单词的方法相同,均为BFS。因此题还需要将所有最短的路径全部输出,
所以需要保存路径中每个单词的前驱,得到前驱后DFS遍历所有最短路径。
步骤:
1,同word ladder,利用BFS来找到相邻单词,因为是BFS,所以可以保证在得到第一条路径后遍历完该层结点就可以结束整个搜索过程,因为BFS方法得到的第一条路径即为最短路径。
2,在1过程中,搜索所有和当前单词只差一个字母的单词,查询新单词是否在字典中同时是否已经存在于变换路径中,如果在字典中同时不在已有的变换路径中,把新单词放入队列,继续BFS。
3,对得到的前驱结点信息进行DFS,从end出发遍历出所有最短路径。
根据上述思路
代码如下,提示超时
class Solution
{
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict)
{
vector<vector<string>> result;
if(start==end)
return result;
unordered_map<string, vector<string>> fatherMap;
queue<string> queuePop, queuePush, queueTemp;
unordered_set<string> tempSet;
bool flag = false;
queuePop.push(start);
while(!queuePop.empty()&&!flag)
{
queue<string> queueTemp = queuePop;
while(!queueTemp.empty())
{
tempSet.insert(queueTemp.front());
queueTemp.pop();
}
while(!queuePop.empty())
{
string str(queuePop.front());
queuePop.pop();
for(int i = 0; i < str.size(); ++i)
for(char j = 'a'; j <= 'z'; ++j)
{
if(str[i]==j)
continue;
char tempChar = str[i];
str[i] = j;
if(str == end)
{
flag = true;
}
if(dict.count(str)&&!tempSet.count(str))
{
string tempStr = str;
tempStr[i] = tempChar;
fatherMap[str].push_back(tempStr);
queuePush.push(str);
}
str[i] = tempChar;
}
}
swap(queuePop, queuePush);
}
vector<string> tempVectorStr;
if(!flag)
return result;
dfsLadders(fatherMap, start, end, tempVectorStr, result);
return result;
}
void dfsLadders(unordered_map<string, vector<string>> &fatherMap, string start, string end, vector<string> tempVectorStr, vector<vector<string>> &result)
{
if(end == start)
{
tempVectorStr.push_back(end);
vector<string> tempVector = tempVectorStr;
reverse(tempVector.begin(), tempVector.end());
result.push_back(tempVector);
tempVectorStr.pop_back();
return;
}
tempVectorStr.push_back(end);
for(int i = 0; i < fatherMap.find(end)->second.size(); ++i)
{
dfsLadders(fatherMap, start, fatherMap.find(end)->second.at(i), tempVectorStr, result);
}
tempVectorStr.pop_back();
}
};
后面参考http://www.cnblogs.com/x1957/p/3526838.html
程序思想一致,代码大同小异,但是其代码Accept,而本人的代码不知道哪里出了问题,后面有时间继续研究。
Accept的代码
class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
vector<vector<string> >ans;
if(start == end) return ans;
unordered_set<string>current , next;
unordered_set<string> flag;
unordered_map<string,vector<string> > father;
current.insert(start);
bool found = false;
while(!current.empty() && !found) {
//expand
for(const auto &x : current) {
flag.insert(x);
}
for(auto x : current) {
for(int i = 0 ; i < x.size() ; ++i) {
for(int j = 'a' ; j <= 'z' ; ++j) {
if(x[i] == j) continue;
string tmp = x;
tmp[i] = j;
if(tmp == end) found = true;
if(dict.find(tmp) != dict.end() && flag.find(tmp) == flag.end()) {
next.insert(tmp);
father[tmp].push_back(x);
}
}
}
}
//end expand
current.clear();
swap(current, next);
}
//start foudn father
if(found) {
vector<string> c;
dfs(ans , father , c , start , end);
}
return ans;
}
private:
void dfs(vector<vector<string> >&ans,
unordered_map<string,vector<string> >& father ,
vector<string>& c ,
string& start ,
string& now) {
c.push_back(now);
if(now == start) {
ans.push_back(c);
reverse(ans.back().begin() , ans.back().end());
c.pop_back();
return;
}
auto que = father.find(now) -> second;
for(auto& x : que) {
dfs(ans , father , c , start , x);
}
c.pop_back();
}
};