-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path127.单词接龙.cpp
119 lines (109 loc) · 3.38 KB
/
127.单词接龙.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
/*
* @lc app=leetcode.cn id=127 lang=cpp
*
* [127] 单词接龙
*/
/**
* 单向 BFS
*/
class Solution_BFS {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
// 转化为 set, 提高查询速度
unordered_set<string> word_set(wordList.begin(), wordList.end());
// 结束单词不存在
if (word_set.find(endWord) == word_set.end()) return 0;
queue<string> queue;
// 开始单词加入队列
queue.push(beginWord);
// 记录已访问单词及其最短到达路径, 初始化, 开始单词为1
unordered_map<string, int> visited{{beginWord, 1}};
while (!queue.empty()) {
string word = queue.front();
queue.pop();
int level = visited[word];
if (word == endWord) return level;
for (int i = 0; i < word.size(); i++) {
char temp = word[i];
for (int j = 0; j < 26; j++) {
word[i] = j + 'a';
// 变换后单词为结束单词
if (word == endWord) return level + 1;
// 变换后单词存在于字典, 且未访问过该单词,
// 记录该最短路径并将其加入队列
if (word_set.find(word) != word_set.end() && !visited.count(word)) {
visited[word] = level + 1;
queue.push(word);
}
}
word[i] = temp;
}
}
// 无法到达结束单词
return 0;
}
};
// @lc code=start
/**
*
*/
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
// 转化为 set, 提高查询速度
unordered_set<string> word_set(wordList.begin(), wordList.end());
// 结束单词不存在
if (word_set.find(endWord) == word_set.end()) return 0;
// 生成双端队列
queue<string> front_queue;
queue<string> back_queue;
front_queue.push(beginWord);
back_queue.push(endWord);
// 记录双端队列访问情况
unordered_set<string> front_visited{beginWord};
unordered_set<string> back_visited{endWord};
int dist = 0;
while (!front_queue.empty()) {
dist++;
// 处理小队列
if (front_queue.size() > back_queue.size()) {
front_queue.swap(back_queue);
front_visited.swap(back_visited);
}
int len = front_queue.size();
// 一次处理完
while (len--) {
string word = front_queue.front();
front_queue.pop();
for (int i = 0; i < word.size(); i++) {
char temp = word[i];
for (int j = 0; j < 26; j++) {
word[i] = j + 'a';
// 当前队列已访问过该词汇, 跳过
if (front_visited.find(word) != front_visited.end()) continue;
// 另一端队列已访问过该词汇, 只需要一步即可到达, 返回 dist + 1
if (back_visited.find(word) != back_visited.end()) return dist + 1;
// 都未访问过
// 新单词存在于字典中, 则添加到队列, 并设为已访问
if (word_set.find(word) != word_set.end()) {
front_queue.push(word);
front_visited.insert(word);
}
}
// 重置状态
word[i] = temp;
}
}
}
// 无法到达结束单词
return 0;
}
};
// @lc code=end