mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
add 127
This commit is contained in:
parent
6484bd3c2a
commit
a37563a3e7
122
solutions/127. Word Ladder.md
Normal file
122
solutions/127. Word Ladder.md
Normal file
@ -0,0 +1,122 @@
|
||||
# [127. Word Ladder](https://leetcode.com/problems/word-ladder/)
|
||||
# 思路
|
||||
词句阶梯: 给了我们一个单词字典,里面有一系列很相似的单词,然后给了一个起始单词和一个结束单词,每次变换只能改变一个单词,并且中间过程的单词都必须是单词字典中的单词,让我们求出最短的变化序列的长度。
|
||||
要求最短路径长度,首先应该想到BFS。类似迷宫里面的最短路求法,迷宫每个点有上下左右四个方向可以走,而这里有26个字母,就是二十六个方向可以走,本质上没有区别。
|
||||
|
||||
另外由于需要频繁判断某个单词是否在字典中,所以我们用hashSet记录词典(代码中的`wordSet`)以快速进行判断。
|
||||
|
||||
## 思路一
|
||||
采用递归的BFS。首先我们用一个词语数组`beginWords`来记录开始的词语,初始化为一个元素`beginWord`,此外类似走迷宫的题目我们还需要一个`visited`来记录当前词语是否被访问过,这里我们用hashSet来定义`visited`。递归出口是`beginWords`为空。
|
||||
|
||||
|
||||
## 思路二、思路一改进
|
||||
仔细分析我们可以发现了个hashSet`wordSet`和`visited`其实在功能上是有冗余的: 如果我们每访问一次`wordSet`里的词然后就把它从`wordSet`中去掉,这样不就不需要`visited`了吗?亲测会比思路一快很多。
|
||||
|
||||
## 思路三
|
||||
思路二的非递归版本。此时就不需要`beginWords`了而需要一个队列。
|
||||
|
||||
# C++
|
||||
## 思路一
|
||||
``` C++
|
||||
class Solution {
|
||||
private:
|
||||
int BFS(vector<string>beginWords, unordered_set<string>&wordSet,
|
||||
unordered_set<string>&visited, string &endWord){
|
||||
vector<string>next_beginWords;
|
||||
string word;
|
||||
for(int i = 0; i < beginWords.size(); i++){
|
||||
for(int j = 0; j < endWord.size(); j++){
|
||||
word = beginWords[i];
|
||||
if(word == endWord) return 1;
|
||||
for(char k = 'a'; k <= 'z'; k++){
|
||||
word[j] = k;
|
||||
if(!wordSet.count(word) || visited.count(word)) continue;
|
||||
|
||||
visited.insert(word);
|
||||
next_beginWords.push_back(word);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(next_beginWords.empty()) return 0; // 递归出口
|
||||
return BFS(next_beginWords, wordSet, visited, endWord) + 1;
|
||||
}
|
||||
|
||||
public:
|
||||
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
|
||||
unordered_set<string>wordSet(wordList.begin(), wordList.end());
|
||||
unordered_set<string>visited{beginWord};
|
||||
if(wordSet.count(endWord) != 1) return 0;
|
||||
vector<string>beginWords{beginWord};
|
||||
return BFS(beginWords, wordSet, visited, endWord);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 思路二
|
||||
``` C++
|
||||
class Solution {
|
||||
private:
|
||||
int BFS(vector<string>beginWords, unordered_set<string>&wordSet, string &endWord){
|
||||
vector<string>next_beginWords;
|
||||
string word;
|
||||
for(int i = 0; i < beginWords.size(); i++){
|
||||
for(int j = 0; j < endWord.size(); j++){
|
||||
word = beginWords[i];
|
||||
if(word == endWord) return 1;
|
||||
char tmp_c = word[j];
|
||||
for(char k = 'a'; k <= 'z'; k++){
|
||||
word[j] = k;
|
||||
// tmp_c == k即新旧单词相同
|
||||
if(!wordSet.count(word) || tmp_c == k) continue;
|
||||
|
||||
wordSet.erase(word);
|
||||
next_beginWords.push_back(word);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(next_beginWords.empty()) return 0; // 递归出口
|
||||
return BFS(next_beginWords, wordSet, endWord) + 1;
|
||||
}
|
||||
|
||||
public:
|
||||
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
|
||||
unordered_set<string>wordSet(wordList.begin(), wordList.end());
|
||||
if(wordSet.count(endWord) != 1) return 0;
|
||||
vector<string>beginWords{beginWord};
|
||||
return BFS(beginWords, wordSet, endWord);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 思路三
|
||||
``` C++
|
||||
class Solution {
|
||||
public:
|
||||
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
|
||||
unordered_set<string> wordSet(wordList.begin(), wordList.end());
|
||||
if (!wordSet.count(endWord)) return 0;
|
||||
queue<string> q;
|
||||
q.push(beginWord);
|
||||
int res = 0;
|
||||
while (!q.empty()) {
|
||||
for (int k = q.size(); k > 0; --k) {
|
||||
string word = q.front(); q.pop();
|
||||
if (word == endWord) return res + 1;
|
||||
for (int i = 0; i < word.size(); ++i) {
|
||||
string newWord = word;
|
||||
for (char k = 'a'; k <= 'z'; ++k) {
|
||||
newWord[i] = k;
|
||||
if (wordSet.count(newWord) && newWord != word) {
|
||||
q.push(newWord);
|
||||
wordSet.erase(newWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user