leetcode127. 单词接龙 单向DFS

  • https://leetcode.cn/problems/word-ladder/

  • 字典 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;
    }


};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值