127. 单词接龙

字典 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

> BFS代码


class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        // 将vector转成unordered_set,提高查询速度
        unordered_set<string> wordSet(wordList.begin(), wordList.end());
        // 如果endWord没有在wordSet出现,直接返回0
        if (wordSet.find(endWord) == wordSet.end()) return 0;
        // 记录word是否访问过
        unordered_map<string, int> visitMap; // <word, 查询到这个word路径长度>
        // 初始化队列
        queue<string> que;
        que.push(beginWord);
        // 初始化visitMap
        visitMap.insert(pair<string, int>(beginWord, 1));

        while(!que.empty()) {
            string word = que.front();
            que.pop();
            int path = visitMap[word]; // 这个word的路径长度
            for (int i = 0; i < word.size(); i++) {
                string newWord = word; // 用一个新单词替换word,因为每次置换一个字母
                for (int j = 0 ; j < 26; j++) {
                    newWord[i] = j + 'a';
                    if (newWord == endWord) return path + 1; // 找到了end,返回path+1
                    // wordSet出现了newWord,并且newWord没有被访问过
                    if (wordSet.find(newWord) != wordSet.end()
                            && visitMap.find(newWord) == visitMap.end()) {
                        // 添加访问信息
                        visitMap.insert(pair<string, int>(newWord, path + 1));
                        que.push(newWord);
                    }
                }
            }
        }
        return 0;
    }
};

> 双向BFS


class Solution {
    string s, e;
    unordered_set <string> S;
public:
    int ladderLength(string st, string ed, vector<string>& wordList) {
        //双向bfs减少搜索空间宽度
        this->s = st, this->e = ed;
        for(string & w: wordList) S.insert(w);
        if(!S.count(ed)) return 0;
        int ans = bfs();
        return ans == -1? 0 : ans + 1;
    }
    int bfs(){
        unordered_map <string, int> m1, m2;
        queue <string> q1, q2;
        m1[s] =0, m2[e] = 0;
        q1.push(s); q2.push(e);
        while(q1.size() && q2.size()){
            int t = -1;
            if(q1.size() <= q2.size()){
                t = update(q1, m1, m2);
            }
            else{
                t = update(q2, m2, m1);
            }
            if(t != -1) return t;
        }
        return -1;
    }
    int update(queue <string> & q, unordered_map <string, int> & now, unordered_map <string, int> & other){
        int m = q.size();
        while(m--){
            string begin = q.front(); q.pop();
            string modify;
            int n =  begin.size();
            for(int i = 0; i < n; i++){
                modify = begin; 
                for(int j = 0; j < 26; j++){
                modify[i] = char(j + 'a');
                    if(S.count(modify)){
                        if(now.count(modify)) continue;
                        if(other.count(modify)){
                            return now[begin] + 1 + other[modify];
                        }
                        else {
                            q.push(modify);
                            now[modify] = now[begin] + 1;
                        }
                    }
                }
            }
        }
        return -1;
    }
};
posted @   xiazichengxi  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
主题色彩