leetcode:127. 单词接龙
题目
字典 wordList
中从单词 beginWord
和 endWord
的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk
:
- 每一对相邻的单词只差一个字母。
- 对于
1 <= i <= k
时,每个si
都在wordList
中。注意,beginWord
不需要在wordList
中。 sk == endWord
给你两个单词 beginWord
和 endWord
和一个字典 wordList
,返回 从 beginWord
到 endWord
的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0
。
示例:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:5
解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:0
解释:endWord "cog" 不在字典中,所以无法进行转换。
解答 & 代码
层序遍历
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
// 将所有单词存储到哈希表,以便能在 O(1) 时间复杂度内判断一个单词是否存在 wordList 中
unordered_set<string> wordsDict(wordList.begin(), wordList.end());
// 如果 endWord 不在 wordList,肯定不存在转换序列,直接返回 0
if(wordsDict.find(endWord) == wordsDict.end())
return 0;
queue<string> wordQ; // 队列,存储层序遍历的节点(单词)
wordQ.push(beginWord);
unordered_set<string> visited; // 哈希表,存储已访问过的单词
visited.insert(beginWord);
int depth = 1; // 当前序列的单词数
// 层序遍历
while(!wordQ.empty())
{
int levelCnt = wordQ.size();
for(int i = 0; i < levelCnt; ++i)
{
string curWord = wordQ.front();
wordQ.pop();
// 对于当前单词的每一位,依次改为 26 个字母
for(int j = 0; j < curWord.size(); ++j)
{
char originCh = curWord[j];
for(int k = 0; k < 26; ++k)
{
curWord[j] = 'a' + k;
// 如果修改后的单词没被访问过,且存在 wordList 中,则存入队列(相当于当前单词的孩子节点)
if(visited.find(curWord) == visited.end() &&
wordsDict.find(curWord) != wordsDict.end())
{
// 如果修改后的单词就是 endWord,直接返回
if(curWord == endWord)
return depth + 1;
else
{
wordQ.push(curWord);
visited.insert(curWord);
}
}
}
curWord[j] = originCh; // 撤销对当前位的修改,去修改下一位字符
}
}
++depth;
}
return 0;
}
};
复杂度分析:设字典 wordList
中包含 n 个单词,设单词长度 m
- 时间复杂度 O(nm26):访问每个单词一次,对于每个单词,遍历其每一位,分别修改为 26 个字母,看修改后的字符是否存在字典中且未被访问过
- 空间复杂度 O(nm):
- 哈希表 wordsDict 存储所有单词,每个单词长为 m
- 队列 wordQ 存储 BFS 遍历的节点(单词),存储的单数 O(n),每个单词长为 m
- 哈希表 visited 存储访问过的单词,最多 n 个,每个单词长为 m
执行结果:
执行结果:通过
执行用时:164 ms, 在所有 C++ 提交中击败了 39.14% 的用户
内存消耗:14.8 MB, 在所有 C++ 提交中击败了 61.99% 的用户