LC 127. Word Ladder 系列之一 BFS

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output: 5

Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Example 2:

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Output: 0

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

只相差一个字母的两个单词是可以相互转换的,将可以转换的单词表示成在图中有连接边的节点,将beginWord到endWord的判断转化为判断从beginWord到endWord是否存在一条可行的路径。题目问的是最少转换的次数,等同于求图上起点到终点的最短路径,用BFS搜索就可以了。

一开始从某个节点找和它邻接的节点,我用的方法是用这个节点和所有其他节点进行判断是否为可转换的,这样做下来时间用的比较长,不太理想。后来参考别人的做法,由于一共只有26个字母,因此可以产生所有可能的可转换的单词,然后检查这个单词是否在给定的单词集合内。频繁的查询怎么提高效率?set。最后做下来跑test cases基本上速度减少了一半。后来做了一些其他BFS的题目,总结出一点经验,在用BFS的时候通常需要合理的设置辅助的set或map来加速查找,例如后来做的LC815 Bus Routes中设置了route和bus对应的、bus和route对应的两个map。BFS和set/map的辅助可以解决很多这类问题。

int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
    queue<string> q;
    unordered_set<string> visited;
    unordered_set<string> wordSet(wordList.begin(), wordList.end());
    int pathLen = 1;
    q.push(beginWord);
    q.push("0");
    while(!q.empty()) {
        string qStr = q.front();
        q.pop();
        if (qStr == "0") {
            pathLen += 1;
            if (q.empty()) {
                return 0;
            }
            q.push("0");
            continue;
        }
        for (int i = 0; i < qStr.length(); i++) {
            string word = qStr;
            for (int j = 0; j <= 25; j++) {
                word[i] = 'a' + j;
                if (visited.find(word) == visited.end() && wordSet.find(word) != wordSet.end()) {
                    if (word == endWord) {
                        return pathLen + 1;
                    }
                    visited.insert(word);
                    q.push(word);
                }
            }
        }
    }
    return pathLen + 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值