LeetCode 126. 单词接龙 II
地址 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;
}
};
127题目类似 不过题目时间要求更高
根据题目提供的数据
单词长度只有10 ,那么将单词每个字符尝试换成其他25个字母,然后查看该单词是否在字典中
时间效率更高
class Solution {
public:
unordered_set<string> ss;
unordered_map<string, int> dis;
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;
}
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
for (auto& e : wordList) ss.insert(e);
if (ss.count(endWord) == 0) return 0;
queue<pair<string, int>> q;
q.push({ beginWord ,1 });
while (!q.empty()) {
pair<string, int> p = q.front(); q.pop();
int step = p.second;
string s = p.first;
if (s == endWord) return step;
for(int i =0;i <s.size();i++){
for(int j = 0; j < 26;j++){
char c = j+'a';
char oldchar = s[i];
s[i]=c;
if(ss.count(s)!=0 && (dis.count(s) == 0||dis[s] > (step+1))){
dis[s] = step+1;
q.push({s,step+1});
}
s[i]=oldchar;
}
}
}
return 0;
}
};
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
![阿里打赏](https://files.cnblogs.com/files/itdef/ali2.bmp)
![微信打赏](https://files.cnblogs.com/files/itdef/weixin2.bmp)