题目链接
思路
- 这种可以抽象成最短路径问题 每个单词是一个结点,如果两个单词只有一个字母的差距,那么他们之间有一条边,最终的目的是寻找开始单词和结束单词的最短路径
- 因此这个题可以用BFS来解决 通过用队列辅助BFS 每一轮遍历结束后都给count++ 这样直到某一次队列中出现了target,就算是最终找到了
- 因此我们可以用一个函数来获取某个单词可以转换为的所有的单词,也就是说在获取所有和该结点相邻的结点,注意这个函数要返回所有相邻的结点,不管是否遍历过
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Queue<String> queue1 = new LinkedList<>() , queue2 = new LinkedList<>();
Set<String> notVisited = new HashSet(wordList);
int min = 1;
queue1.offer(beginWord);
while(!queue1.isEmpty()){
String word = queue1.poll();
if(word.equals(endWord))
return min;
List<String> neighbors = getNeighbors(word);
for(String neighbor :neighbors){
if(notVisited.contains(neighbor)){
notVisited.remove(neighbor);
queue2.offer(neighbor);
}
}
if(queue1.isEmpty()){
queue1 = queue2;
queue2 = new LinkedList<>();
min++;
}
}
return 0;
}
private List<String> getNeighbors(String word){
List<String> neighbors = new ArrayList<>();
char[] words = word.toCharArray();
for(int i = 0 ; i < words.length ; i++){
char oldChar = words[i];
for(int j = 0 ; j < 26 ; j++){
char newChar = (char)('a' + j);
if(newChar != oldChar){
words[i] = newChar;
neighbors.add(new String(words));
}
words[i] = oldChar;
}
}
return neighbors;
}
}
- 在此基础上可以有一个优化~ 就是双向奔赴!
- 上一种做法是用一个队列 从开始单词结点搜索 直到搜索到target结点
- 现在我们可以用两个集合来保存,一开始set1存开始结点 set2存结束结点,然后把set1当上一种做法的队列使用
- 每次在开始遍历set找临近结点时,选择set1和set2中小的那个遍历~ 如果某一步出现了另一个集合中的元素,那么就说明已经找到啦!
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> notVisited = new HashSet(wordList),set1 = new HashSet<>(),set2 = new HashSet<>(),set3;
set1.add(beginWord);
set2.add(endWord);
int min = 2;
if(!notVisited.contains(endWord))
return 0;
while(!set1.isEmpty() && !set2.isEmpty()){
if(set1.size() > set2.size()){
set3 = set1;
set1 = set2;
set2 = set3;
}
set3 = new HashSet();
for(String word: set1){
List<String> neighbors = getNeighbors(word);
for(String neighbor : neighbors){
if(set2.contains(neighbor))
return min;
if(notVisited.contains(neighbor)){
notVisited.remove(neighbor);
set3.add(neighbor);
}
}
}
set1 = set3;
min++;
}
return 0;
}
private List<String> getNeighbors(String word){
List<String> neighbors = new ArrayList<>();
char[] words = word.toCharArray();
for(int i = 0 ; i < words.length ; i++){
char oldChar = words[i];
for(int j = 0 ; j < 26 ; j++){
char newChar = (char)('a' + j);
if(newChar != oldChar){
words[i] = newChar;
neighbors.add(new String(words));
}
words[i] = oldChar;
}
}
return neighbors;
}
}