解析:这道题还是比较难的,我第一次看没有什么思路,实则考察的核心是广度优先检索
分析:由于每个单词都是由26个字母组成,即意味着变换下一个单词就是从其它25个字母当中选择其中一个(本身重复的不计在内),单词的每一个位置都是如此,有点类似于走迷宫,只不过迷宫每次只有上下左右四个方向进行选择,但本质上还是一样的,所有可以采用广度优先检索去一层一层检索,直到最终目标出现,或走到头.
用队列allWord存储当前层的所有的状态,并采用空串作为层结束标识:
1.检索当前层:分别对每个元素当中的每个位置用25个其他字母的替换,然后和终止状态endWord进行比较,如果相同,返回当前层;若不相同,继续搜索
2.检索下一层:上一层中存储的所有可能状态即为下一层检索的状态,重复进行1,直至找到最终状态或者遍历完所有可能的状态
注意:为了防止回溯到之前出现过的状态(死循环),当队列中新增加一种状态(单词)时,要将字典中的当前状态对应的单词去除
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
set<string> wordSet(wordList.begin(), wordList.end());
if (!wordSet.count(endWord)) return 0;
queue<string> allWord{{beginWord, ""}}; //将""串作为下一层结束的标记
int cur = 1;
while (!allWord.empty()){
cur++;
while (allWord.front() != ""){ //搜索下一层
string word = allWord.front();
allWord.pop();
for (int i = 0; i < word.length(); ++i){
string new_word = word;
for (char ch = 'a'; ch <= 'z'; ch++){ //在26个字母之间替换
new_word[i] = ch;
if (new_word == word) continue;
if (wordSet.count(new_word)){
if (new_word == endWord) return cur;
allWord.push(new_word);
wordSet.erase(new_word); //关键
}
}
}
}
allWord.pop();
allWord.push("");
if (allWord.front() == "") break; //关键,当前的单词如果为空,意味着已经结束
}
return 0;
}
};
[1]https://www.cnblogs.com/grandyang/p/4539768.html