Leetcode, WordLadder2
虽然不太懂,但还是记录一下,参考soulmachine
#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>
using namespace std;
void gen_path(unordered_map<string, vector<string>> &father, vector<string> &path,
const string &start, const string &word, vector<vector<string>> &res)
{
path.push_back(word);
if ( word == start )
{
res.push_back(path);
reverse(res.back().begin(), res.back().end());
}
else
{
for (const auto &f : father[word])
{
gen_path(father, path, start, f, res);
}
}
path.pop_back();
}
//时间复杂度O(n),空间复杂度O(n)
vector<vector<string>> solution(const string& start, const string &end,
const unordered_set<string> &dict)
{
unordered_set<string> current, next; //当前层
unordered_set<string> visited; //判重
unordered_map<string, vector<string>> father;
bool found = false;
auto state_is_target = [&](const string &s) { return s == end; };
//改变每个位置字符,找在字典出现的字符串
auto state_extend = [&](const string &s) {
unordered_set<string> result;
for (size_t i = 0; i < s.size(); ++i)
{
string new_word(s);
for (char c = 'a'; c <= 'z'; ++c)
{
if (c == new_word[i])
continue;
swap(c, new_word[i]);
if ((dict.count(new_word) > 0 || new_word == end) &&
!visited.count(new_word))
{
result.insert(new_word);
}
swap(c, new_word[i]); //恢复该单词
}
}
return result;
};
current.insert(start);
while (!current.empty() && !found)
{
//将本层置为已访问,防止同层之间互相指向
for (const auto &word : current)
visited.insert(word);
for (const auto &word : current)
{
const auto &new_states = state_extend(word);
for (const auto &state : new_states)
{
if (state_is_target(state))
{
found = true; //找到了
}
next.insert(state);
father[state].push_back(word);
}
}
current.clear();
swap(next, current);
}
vector<vector<string>> res;
if (found)
{
vector<string> path;
gen_path(father, path, start, end, res);
}
return res;
}
int main()
{
string start = "hit";
string end = "cog";
unordered_set<string> dict = { "hot", "dot", "dog", "lot", "log" };
auto res = solution(start, end, dict);
//{
// ["hit", "hot", "lot", "log", "cog"],
// ["hit", "hot", "dot", "dog", "cog"]
//}
return 0;
}