[LeetCode] 127. Word Ladder Java
题目:
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
- Only one letter can be changed at a time.
- Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
题意及分析:给出一个开始字符串和结束字符串,每次从wordList中取出一个word,这个word和前一个只能有一个字符不一样,求从开始字符串到结束字符串的最短距离。这道题我开始用的dfs查找,首先用一个hashMap保存每个word的可相差一个字符的word,然后判断是否已经遍历过来查找,这样会超时。另一种是使用BFS查找。
方法一:只使用一个Queue的BFS,用一个queue来保存某一层所有可能的情况,这样当发现等于endWord时,就可以直接返回结果。
代码:
class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { HashSet<String> hashSet = new HashSet<>(); //用来保存已经使用过的word Queue<String> queue = new LinkedList<>(); //用来进行帮助进行BFS queue.add(beginWord); queue.add(null); //用来标记每一层结束,也可以用size或者在创建queue hashSet.add(beginWord); int level = 1; //用来记录最短的到达方法 while(!queue.isEmpty()){ String now = queue.poll(); if(now != null){ for(int i=0;i<wordList.size();i++){ if(onlyOneWorld(now,wordList.get(i))){ //加入下一层的所有的可能情况 if(!hashSet.contains(wordList.get(i))){ if(wordList.get(i).equals(endWord)) return level+1; hashSet.add(wordList.get(i)); queue.add(wordList.get(i)); } } } }else{ //遍历完一层 level++; if (!queue.isEmpty()) { queue.add(null); } } } return 0; } private boolean onlyOneWorld(String s1,String s2){ //判断两个字符串是否只有一个字符不一样 int count = 0; for(int i=0;i<s1.length();i++){ if(s1.charAt(i) != s2.charAt(i)) count++; } return count==1?true:false; } }
方法二:从前往后、从后往前同时查找,可以缩短查找时间
class Solution { private boolean onlyOneWorld(String s1,String s2){ //判断两个字符串是否只有一个字符不一样 int count = 0; for(int i=0;i<s1.length();i++){ if(s1.charAt(i) != s2.charAt(i)) count++; } return count==1?true:false; } //使用一个beginSet和endSet这样可以缩短查询时间,从begin和从end开始,如果begin下一个可能在end中,那么直接可以达到 public int ladderLength(String beginWord, String endWord, List<String> wordList) { if(!wordList.contains(endWord)) return 0; HashSet<String> hashSet = new HashSet<>(); //用来保存已经使用过的word Set<String> beginSet = new HashSet<String>(), endSet = new HashSet<String>(); beginSet.add(beginWord); endSet.add(endWord); int level = 1; while(!beginSet.isEmpty() && !endSet.isEmpty()){ if(beginSet.size()>endSet.size()){ //每次查找较小的 Set<String> set = beginSet; beginSet = endSet; endSet = set; } HashSet<String> temp = new HashSet<>(); for(String str : beginSet){ for(int i=0;i<wordList.size();i++){ String a = wordList.get(i); if(onlyOneWorld(str,a)&&endSet.contains(a)) return level + 1; if(!hashSet.contains(a) && onlyOneWorld(str,a)){ //未被访问过 hashSet.add(a); temp.add(a); } } } beginSet = temp; level++; } return 0; } }