题目链接:https://leetcode-cn.com/problems/word-ladder-ii/
题意:
按字典 wordList 完成从单词 beginWord 到单词 endWord 转化,一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> ... -> sk 这样的单词序列,并满足:
每对相邻的单词之间仅有单个字母不同。
转换过程中的每个单词 si(1 <= i <= k)必须是字典 wordList 中的单词。注意,beginWord 不必是字典 wordList 中的单词。
sk == endWord
给你两个单词 beginWord 和 endWord ,以及一个字典 wordList 。请你找出并返回所有从 beginWord 到 endWord 的 最短转换序列 ,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表 [beginWord, s1, s2, ..., sk] 的形式返回。
方法:哈希表作图,利用宽度搜索遍历所有图的边,利用深度搜索查找所有的最短序列,效率比较低
class Solution {
private:
vector<vector<string>> ret;//返回的向量
unordered_map<string,unordered_set<string>> mp;//哈希表作图,<字符串,与它相邻的字符串>
int minL = 0;//存储最短序列的长度
void dfs(vector<string> vct,int level,string beginWord)//已经搜索的向量,目前到了第几层,结束的字符串是什么
{
string str = vct.back();//存储向量中最后一个元素
if(level==minL)//如果层数达到了最后一层
{
if(str==beginWord)//最后一个单词时起始单词,将向量反转以后插入向量中
{
reverse(vct.begin(),vct.end());//反转,使用<algorthm>中的reverse()
//arrayRever=arrayInt;
//reverse(arrayRever.begin(),arrayRever.end());
ret.push_back(vct);//插入返回向量
}
else
return ;//否则直接结束返回
}
for(auto iter=mp[str].begin();iter!=mp[str].end();iter++)//继续深搜图中的每一个元素
{
vct.emplace_back(*iter);//在这个向量尾部插入图中第i个元素
dfs(vct,level+1,beginWord);
vct.pop_back();//把尾部元素删掉,影响下一个元素插入
//c++可以使用 vector 的成员函数 pop_back() 来删除容器尾部的元素
}
}
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
//广搜建图
queue<pair<string,int>> Q;//用来辅助广搜
Q.push({beginWord,1});//往队列中插入起始字符串
unordered_set<string> se;//集合辅助广搜
for(auto& word:wordList)//更新集合
{
se.insert(word);
}
se.erase(beginWord);//开始的字符串要删掉
if(se.find(endWord)==se.end()) return ret;//如果在集合总没找到最后一个字符串,直接返回
while(!Q.empty())//当队列不为空时,就不停的建图,
{
string str = Q.front().first;//取出队首元素的字符串
int level = Q.front().second;
Q.pop();//弹出队首元素
se.erase(str);//在集合中删除对应的字符串
if(str==endWord&&minL==0)
{
minL = level;//标记存在转换序列
continue ;
}
for(int i=0;i<str.size();i++)
{
for(int j=0;j<26;j++)
{
string tmp = str;//暂存字符串,避免str字符串被改变两个字符以上
tmp[i] = j+'a';//替换对应的字符,查找集合中是否存在对应的字符串
if(se.find(tmp)!=se.end())//如果在集合中的话,就往图里面加边
{
mp[tmp].insert(str);//key值为tmp对应的哈希项的value向量中插入str,
Q.push({tmp,level+1});//队列中插入tmp字符串
}
}
}
}
if(!minL) return ret;//不存在转换序列
vector<string> vct;//定义最短转换序列的向量
vct.emplace_back(endWord);//插入最后一个元素
//深搜找序列,长度达到minL就停止
dfs(vct,1,beginWord);
return ret;
}
};