127. 单词接龙
原题链接:
https://leetcode.cn/problems/word-ladder/description/
完成情况:
解题思路:
这段代码是一个用于寻找从beginWord到endWord的最短转换序列长度的算法。以下是代码的清晰解释:
- 创建一个HashSet 'wordSet',其中存储了给定的单词列表,以加快查找速度。
- 检查特殊情况:如果wordSet为空或者不包含endWord,则直接返回0。
- 创建一个队列 'queue' 用于BFS(广度优先搜索)。
- 将beginWord加入队列,并创建一个HashMap 'map',用于记录每个单词对应的路径长度,将beginWord对应长度设置为1。
- 在队列不为空的情况下,执行以下循环:
- 取出队列头部的单词 'word'。
- 获取 'word' 对应的路径长度 'path'。
- 遍历 'word' 的每个字符:
- 将 'word' 转换为字符数组 'chars',以便替换字符。
- 从 'a' 到 'z' 遍历替换第i个字符。
- 构建新的单词 'newWord'。
- 如果 'newWord' 等于 endWord,则返回当前路径长度加1。
- 如果 'newWord' 在wordSet中且未被访问过,则将其路径长度记录在map中,并加入队列。
- 如果未找到路径,则返回0。
这段代码使用BFS算法,通过逐个替换单词中的字符来寻找从beginWord到endWord的最短转换序列长度。
参考代码:
_127单词接龙
java
package 代码随想录.图论;
import java.util.*;
public class _127单词接龙 {
/**
* 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。
* 如果不存在这样的转换序列,返回 0 。
* @param beginWord
* @param endWord
* @param wordList
* @return
*/
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
//每次只能变动一个字符,且变化后的单词,必须是wordList里面的单词,,然后求 【最短转换序列 中的 单词数目】,,如果找不到,则返回false
//上来先进行去重操作
HashSet<String> wordSet = new HashSet<String>(wordList);//去重后,每次尝试修改一个,不要想的太复杂
if (wordList.size() == 0 || !wordList.contains(endWord)){ //去除空集
return 0;
}
Deque<String> myQueue = new LinkedList<String>();
myQueue.offer(beginWord);
Map<String,Integer> map = new HashMap<>(); //记录走到当前位置所需最短步长
map.put(beginWord,1);
while (!myQueue.isEmpty()){
String wordSection = myQueue.poll(); //取出当前队头元素
int pathList = map.get(wordSection); //记录其到达长度
for (int i = 0;i<wordSection.length();i++){ //逐个单词,逐一替换,进行尝试
char [] chars = wordSection.toCharArray(); //将单词转换为charArray,方便逐一判断与替换
for (char ch = 'a';ch <= 'z';ch++){
chars[i] = ch; //逐一单词尝试去进行替换,同时判别一下是否存在当前这一单词序列
String comWord = String.valueOf(chars); //转回String
if (comWord.equals(endWord)){ //如果与最终答案完全匹配
return pathList+1; //记录在案
}
if (wordSet.contains(comWord) && !map.containsKey(comWord)){ //如果新单词在set中,但是没有访问过
map.put(comWord,pathList+1); //记录在案
myQueue.offer(comWord); //并记录尾端
}
}
}
}
return 0;
}
}
_127单词接龙_bfs
java
package 代码随想录.图论;
import java.util.*;
public class _127单词接龙_bfs {
/**
*
* @param beginWord
* @param endWord
* @param wordList
* @return
*/
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
if (wordList.size() == 0 || !wordList.contains(endWord)){ //去除空集
return 0;
}
int resLeft = 0,resRight = 0;
Queue<String> queueLeft = new ArrayDeque<String>(),queueRight = new ArrayDeque<String>();
queueLeft.add(beginWord);
queueRight.add(endWord);
//左右两边,同时开始找
//从beginword开始bfs时,把遍历到的节点存入hashSetLeft中
//从endWord开始bfs时,把遍历到的节点存入hashSetRight中
Set<String> hashSetLeft = new HashSet<String>();
Set<String> hashSetRight = new HashSet<String>();
hashSetLeft.add(beginWord);
hashSetRight.add(endWord);
//判断两边能否构成连接通路
//只要有一个队列为空,说明beginWord就无法转化到endWord
while (!queueLeft.isEmpty() && !queueRight.isEmpty()){
//左端点检测
++resLeft;
int size = queueLeft.size();
for (int i = 0;i<size;i++){
String curWord = queueLeft.poll();
//判别右边能否与左边匹对上
if (hashSetRight.contains(curWord)) return resLeft + resRight;
//-----------------------------------------------------------------
for(String chooseWord : wordList){
if (hashSetLeft.contains(chooseWord) || !isVaild(curWord,chooseWord)) continue;
hashSetLeft.add(chooseWord);
queueLeft.add(chooseWord);
}
}
//右端点检测
++resRight;
size = queueRight.size();
for (int i = 0;i<size;i++){
String curWord = queueRight.poll();
//只要hashSetLeft中存在curWord,说明从curWord可以转换到 endWord
if(hashSetLeft.contains(curWord)) return resLeft + resRight;
for(String chooseWord : wordList){
if (hashSetRight.contains(chooseWord) || !isVaild(curWord,chooseWord)) continue;
hashSetRight.add(chooseWord);
queueRight.add(chooseWord);
}
}
}
return 0;
}
/**
* 判断curWord与chooseWord是否误差仅为1个字符
* @param curWord
* @param chooseWord
* @return
*/
private boolean isVaild(String curWord, String chooseWord) {
int count = 0;
for (int i = 0;i<curWord.length();i++){
if (curWord.charAt(i) != chooseWord.charAt(i)){
++count;
}
}
return count == 1;
}
}