LeetCode 126. Word Ladder的进阶,需要用到126里的处理办法:
1. dict.insert(end), 将end加入到dict中,这样不用到最后再特判
2. 对于每个字符串,每次只变换它个一个字母,看这个新串是否在dict中(详情见126题解)
同时感觉思路不像网上一些博主说的那么复杂...
用dis(map<string, int>类型)记录每个单词离start的距离,通过BFS记录每个单词的前继单词paths(map<string, vector<string>>);
再通过paths信息从end递归(可以理解为DFS), 求出到end的道路即可。
不过这题是比较难...
代码:
class Solution
{
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict)
{
queue<string> q;
q.push(start);
dis[start] = 1;
dict.insert(end);
while (q.empty() == false)
{
string cur = q.front();
for (size_t i = 0; i < cur.size(); ++ i)
{
for (int j = 0; j < 26; ++ j)
{
string tmp = cur;
tmp[i] = 'a' + j;
if (dict.find(tmp) != dict.end())
{
if (dis.find(tmp) == dis.end())
{
dis[tmp] = dis[cur] + 1;
paths[tmp].push_back(cur);
q.push(tmp);
} else if (dis[cur] + 1 == dis[tmp])
{
paths[tmp].push_back(cur);
}
}
}
}
dict.erase(cur);
q.pop();
}
return recurse(end);
}
private:
vector<vector<string>> recurse(const string& cur)
{
vector<vector<string>> ret;
for (auto it = paths[cur].begin(); it != paths[cur].end(); ++ it)
{
vector<vector<string>> tmp(recurse(*it));
for (auto itt = tmp.begin(); itt != tmp.end(); ++ itt)
{
itt->push_back( cur );
ret.push_back(*itt);
}
}
if (dis[cur] == 1)
{
ret.push_back( vector<string>(1, cur) ); // cur==begin
}
return ret;
}
map<string, int> dis;
map<string, vector<string>> paths;
};