给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
说明:
如果不存在这样的转换序列,返回 0。
所有单词具有相同的长度。
所有单词只由小写字母组成。
字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:
输入: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] 输出: 5 解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
示例 2:
输入: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] 输出: 0 解释: endWord "cog" 不在字典中,所以无法进行转换。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder
思路:
好吧,有点搞脑子了
把这个问题理解成,树的形式
上一个问题中,每次往下走一层,是减去他之前的平方数,这个问题往下走一层是看有哪些字典中的节点是可以通过只改变一个字符变成他
从力扣上摘的0.0,这是考虑建模成树,往下BFS遍历,还可以考虑建模成图,等下看。
哇,兄弟,我心态崩了呀,纯自己手打,一个小时了还是红的,哎,没办法,谁叫我总是考虑不够周到呢0.0
我哭辽,你呢,就一句代码,我改了将近一个小时。。。标红了,下次自己长记性吧
class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { //第一步:定义一个新的动态数组来存放wordList List<String> dictionary = new ArrayList<>(wordList); //第二步:基础准备 // 定义一个队列用来存储当前节点 List<String> queue = new ArrayList<>(); queue.add(beginWord); //定义一个变量来记录深度 int deep = 0; //第三步:开始基础的while循环BFS遍历 //定义一个数组来记录是否已经判断过 boolean [] isOrNo = new boolean[dictionary.toArray().length]; boolean flag = false; for (String find : dictionary){ if (find.equals(endWord)){ flag = true; } } if (!flag){ return 0; } while (queue.size() > 0){ //每进行完一轮,深度加一 deep++; //记录下一层的应有元素 List<String> next_queue = new ArrayList<>(); for (String a : queue){ int i = -1; for (String b : dictionary){ //对象数据类型要用equals来判断 i++; if (a.equals(endWord) && !isOrNo[i] && b.length() != 1){ return deep; }else if (b.length() == 1 && a.equals(b) && !isOrNo[i]){ return deep + 1; }else if (changeOneWord(a,b) && !isOrNo[i]){ if (!b.equals(endWord)){ isOrNo[i] = true; } next_queue.add(b); } } } queue = next_queue; } return 0; } public static boolean changeOneWord(String s,String t){ int count = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) != t.charAt(i)){ count++; //增加一个判断加快整体的判断速度 if (count > 1) { return false; } } } return count == 1; } }