-
字典 wordList 中从单词 beginWord 和 endWord 的
转换序列
是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk: -
每一对相邻的单词只差一个字母。
-
对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
-
sk == endWord
给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目
。如果不存在这样的转换序列,返回 0 。
示例 1:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:5
解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
示例 2:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:0
解释:endWord "cog" 不在字典中,所以无法进行转换。
题解
- 更改建图的代码,通过
class Solution {
public:
map<string,vector<string>> graph;
bool can_trans(string A, string B){
int cnt = 0;
for (int i = 0; i < A.size(); i++){
if (A[i] != B[i]) cnt++;//计算两个单词之间的距离
}
return cnt==1;
}
//寻找当前单词的所有邻接单词
vector<string> findAdj(string& target, vector<string>& wordList){
return graph[target];
}
//进行bfs,如果能在遍历完之前找到,则返回遍历的深度
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
queue<string> myqueue;
map<string,bool> visit;//图的遍历过程中防止循环访问
//初始化visit map
for(auto v: wordList){
visit[v] = false;
}
//建图
wordList.push_back(beginWord);
for(int i=0;i<wordList.size();i++)
for(int j=i+1;j<wordList.size();j++)//避免重复
{
if(can_trans(wordList[i],wordList[j])==true)
{
graph[wordList[i]].push_back(wordList[j]);
graph[wordList[j]].push_back(wordList[i]);
}
}
int depth = 1;
myqueue.push(beginWord);visit[beginWord] = true;
while(!myqueue.empty()){
int size=myqueue.size();
depth++;
for(int i=0;i<size;i++) //每一次循环代表宽度增1
{
string startpoint = myqueue.front();
//cout << startpoint<< "=>" ;
myqueue.pop();
// depth++;
for(auto v: findAdj(startpoint,wordList) ){
//out << v<< "->" ;
if(!visit[v]){
myqueue.push(v);if(v == endWord){return depth;} ;visit[v] = true;
}
}
//break;
}
}
return 0;
}
};
错解
- 直接BFS以计算最短路径,但是深度计数是错误的
class Solution {
public:
bool can_trans(string A, string B){
int cnt = 0;
for (int i = 0; i < A.size(); i++){
if (A[i] != B[i]) cnt++;//计算两个单词之间的距离
}
return cnt==1;
}
//寻找当前单词的所有邻接单词 建图
vector<string> findAdj(string& target, vector<string>& wordList){
vector<string> res;
for (const auto& word : wordList){
if(can_trans(target, word)){
res.push_back(word);
}
}
return res;
}
//进行bfs,如果能在遍历完之前找到,则返回遍历的深度
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
queue<string> myqueue;
map<string,bool> visit;//图的遍历过程中防止循环访问
//初始化visit map
for(auto v: wordList){
visit[v] = false;
}
int depth = 1;
myqueue.push(beginWord);
while(!myqueue.empty()){
string startpoint = myqueue.front();
cout << startpoint<< "=>" ;
myqueue.pop();
depth++;
for(auto v: findAdj(startpoint,wordList) ){
cout << v<< "->" ;
if(!visit[v]){
myqueue.push(v);if(v == endWord){return depth;} ;visit[v] = true;
}
}
cout << endl ;
//break;
}
return 0;
}
};
- 输出
hit=>hot->
hot=>dot->lot-> //hit 和 hot在同一层,hot不该计算深度
dot=>hot->dog->lot->
lot=>hot->dot->log->
dog=>dot->log->cog->
- 超出时间限制
class Solution {
public:
map<string,vector<string>> graph;
bool can_trans(string A, string B){
int cnt = 0;
for (int i = 0; i < A.size(); i++){
if (A[i] != B[i]) cnt++;//计算两个单词之间的距离
}
return cnt==1;
}
//寻找当前单词的所有邻接单词
vector<string> findAdj(string& target, vector<string>& wordList){
return graph[target];
}
//进行bfs,如果能在遍历完之前找到,则返回遍历的深度
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
queue<string> myqueue;
map<string,bool> visit;//图的遍历过程中防止循环访问
//初始化visit map
for(auto v: wordList){
visit[v] = false;
}
//建图
vector<string> res;
vector<string> test = wordList;
test.push_back(beginWord);
for(const auto& startword : (test) ){
res = {};
for (const auto& word : wordList){
if(can_trans(startword, word)){
res.push_back(word);
}
}
graph[startword] = res;
}
int depth = 1;
myqueue.push(beginWord);
while(!myqueue.empty()){
int size=myqueue.size();//“当前层的元素个数”
depth++;
for(int i=0;i<size;i++) //每一次循环代表宽度增1
{
string startpoint = myqueue.front();
//cout << startpoint<< "=>" ;
myqueue.pop();
// depth++;
for(auto v: findAdj(startpoint,wordList) ){
//out << v<< "->" ;
if(!visit[v]){
myqueue.push(v);if(v == endWord){return depth;} ;visit[v] = true;
}
}
//break;
}
}
return 0;
}
};
- 更改建图的代码,通过
class Solution {
public:
map<string,vector<string>> graph;
bool can_trans(string A, string B){
int cnt = 0;
for (int i = 0; i < A.size(); i++){
if (A[i] != B[i]) cnt++;//计算两个单词之间的距离
}
return cnt==1;
}
//寻找当前单词的所有邻接单词
vector<string> findAdj(string& target, vector<string>& wordList){
return graph[target];
}
//进行bfs,如果能在遍历完之前找到,则返回遍历的深度
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
queue<string> myqueue;
map<string,bool> visit;//图的遍历过程中防止循环访问
//初始化visit map
for(auto v: wordList){
visit[v] = false;
}
//建图
// vector<string> res;
// vector<string> test = wordList;
// test.push_back(beginWord);
// for(const auto& startword : (test) ){
// res = {};
// for (const auto& word : wordList){
// if(can_trans(startword, word)){
// res.push_back(word);
// }
// }
// graph[startword] = res;
// }
wordList.push_back(beginWord);
for(int i=0;i<wordList.size();i++)
for(int j=i+1;j<wordList.size();j++)//避免重复
{
if(can_trans(wordList[i],wordList[j])==true)
{
graph[wordList[i]].push_back(wordList[j]);
graph[wordList[j]].push_back(wordList[i]);
}
}
int depth = 1;
myqueue.push(beginWord);visit[beginWord] = true;
while(!myqueue.empty()){
int size=myqueue.size();
depth++;
for(int i=0;i<size;i++) //每一次循环代表宽度增1
{
string startpoint = myqueue.front();
//cout << startpoint<< "=>" ;
myqueue.pop();
// depth++;
for(auto v: findAdj(startpoint,wordList) ){
//out << v<< "->" ;
if(!visit[v]){
myqueue.push(v);if(v == endWord){return depth;} ;visit[v] = true;
}
}
//break;
}
}
return 0;
}
};