Keshawn_lu's Blog

Leetcode 127. 单词接龙

字数统计: 660阅读时长: 3 min
2020/11/09 Share

题目简介:

给定两个单词(beginWordendWord)和一个字典,找到从 beginWordendWord 的最短转换序列的长度。转换需遵循如下规则:

  1. 每次转换只能改变一个字母。
  2. 转换过程中的中间单词必须是字典中的单词。

说明:

  • 如果不存在这样的转换序列,返回 0。
  • 所有单词具有相同的长度。
  • 所有单词只由小写字母组成。
  • 字典中不存在重复的单词。
  • 你可以假设 beginWordendWord 是非空的,且二者不相同。

示例 1:

1
2
3
4
5
6
7
8
9
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5

解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
返回它的长度 5。

示例 2:

1
2
3
4
5
6
7
8
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0

解释: endWord "cog" 不在字典中,所以无法进行转换。

思路:

先根据 能否通过改变一个字母转化为另一个单词,从而将单词间的联系构建成一张图,如下图所示:

所以我们要做的就是找到beginWordendWord的最短路径。

定义一个哈希表来存储遍历过的单词,防止重复访问。

然后利用广度优先搜索,记录路径长度,当搜索到某个单词等于endWord时,便可以返回结果了;若最后队列为空,则说明无法转化,返回0即可。

代码如下:

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
class Solution {
public:

unordered_map<string, vector<string>> graph;
unordered_set<string> visit; //避免重复访问

//根据可转换单词建图
void construct(string& beginWord, vector<string>& wordList){

wordList.push_back(beginWord);

for(int i = 0; i < wordList.size(); i++){

for(int j = i + 1; j < wordList.size(); j++){

if(judge(wordList[i], wordList[j])){

graph[wordList[i]].push_back(wordList[j]);
graph[wordList[j]].push_back(wordList[i]);
}
}
}
}

//判断能否进行转化
bool judge(string& word1, string& word2){

int num = 0;
for(int i = 0; i < word1.size(); i++){

if(word1[i] != word2[i])
num++;

if(num > 1)
return false;
}

return true;
}

int ladderLength(string beginWord, string endWord, vector<string>& wordList) {

construct(beginWord, wordList);

int res = 1;
queue<string> qu;

qu.push(beginWord);
visit.insert(beginWord);

while(!qu.empty()){

int size = qu.size();
for(int i = 0; i < size; i++){

vector<string> neighbor = graph[qu.front()];
qu.pop();

for(int j = 0; j < neighbor.size(); j++){

//未被访问到过
if(visit.find(neighbor[j]) == visit.end()){

qu.push(neighbor[j]);
visit.insert(neighbor[j]);
}

if(neighbor[j] == endWord)
return res + 1;
}
}
res++; //遍历一次就加1
}

return 0;
}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: