地址 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] 的形式返回。
示例 1:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
解释:存在 2 种最短的转换序列:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"
示例 2:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:[]
解释:endWord "cog" 不在字典 wordList 中,所以不存在符合要求的转换序列。
提示:
1 <= beginWord.length <= 7
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord、endWord 和 wordList[i] 由小写英文字母组成
beginWord != endWord
wordList 中的所有单词 互不相同
算法1
可以考虑每个单词 作为一个节点,每两个相差不超过一个字符的单词划上连线
那么就制作出一个图,我们求出最短路径即可
这里考虑另一种做法 使用哈希加BFS
BFS的广度遍历性质使得它处理最短路径有天然优势
在使用哈希记录每个单词到起点的最短距离避免重复选择,遍历完成后就得到答案。
C++ 代码
class Solution {
public:
unordered_set<string > ss;
vector<vector<string>> ans;
unordered_map < string, int > mDis;
bool Check(const string& a, const string& b) {
if (a == b) return false;
if (a.length() != b.length()) return false;
int diff=0;
for(int i = 0; i < a.size();i++){
if(a[i] != b[i]) diff++;
if(diff>1) return false;
}
return true;
}
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
for(auto&e:wordList) ss.insert(e);
//包含结尾单词 直接结束
if (ss.count(endWord) == 0) return ans;
queue<vector<string>> q;
vector<string> tmp{ beginWord };
mDis[beginWord] = 1;
q.push(tmp);
while (!q.empty()) {
vector<string> curr = q.front(); q.pop();
if (curr.back() == endWord) {
ans.push_back(curr);
continue;
}
for (auto it = ss.begin(); it != ss.end();it++) {
if ( (mDis.count(*it) == 0 || mDis[*it] > curr.size()) && Check(*it, curr.back()) == true) {
curr.push_back(*it);
q.push(curr);
mDis[*it] = curr.size();
curr.pop_back();
}
}
}
return ans;
}
};