LeetCode127. Word Ladder
Posted 进击的算法
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode127. Word Ladder相关的知识,希望对你有一定的参考价值。
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.
一刷:
思路:非常妙的一个题。开始并没有想到要用图的BFS,但是题目的暗示:求最短变换路径的长度,其实就可以转换成求图的最短路径长度。可以将每个单词视为一个节点,然后如果可以相互转换的则认为在图中是相连的。
用bfs解决最短路径有三个关键点:
-
如何找到当前点的相邻点:方法一是直接从集合里搜,时间复杂度是n*w,n是集合中单词个数,w是每个单词的长度,当集合里有成千上万个单词时这显然不是一种好方法;方法二是将当前单词的每个字母都用a-z中的字母代替,看集合中有没有代替后的这个单词,如果有则加入相邻点的list。
- 如何判重:即访问过的点不能再访问了。
- 找到节点后如何backtracking找到经过的路径。
public int ladderLength(String beginWord, String endWord, List<String> wordList) { HashSet<String> dict=new HashSet<String>(); if(wordList.size()==0 || wordList==null){ return 0; } for(String s:wordList){ dict.add(s); } HashSet<String> visited=new HashSet<String>(); Queue<String> queue=new LinkedList<String>(); if(beginWord.equals(endWord)){ return 1; } int pathLength=1; queue.add(beginWord); visited.add(beginWord); while(!queue.isEmpty()){ int size=queue.size(); pathLength++; for(int i=0;i<size;i++){ String word=queue.poll(); for(String nextWord:getNextWord(word,dict)){ if(!visited.contains(nextWord)){ if(nextWord.equals(endWord)){ return pathLength; } visited.add(nextWord); queue.add(nextWord); } } } } return 0; } private List<String> getNextWord(String word,HashSet<String> dict){ List<String> ret=new ArrayList<String>(); for(char c=‘a‘;c<=‘z‘;c++){ for(int i=0;i<word.length();i++){ if(c==word.charAt(i)){ continue; } String nextWord=wordReplace(word,i,c); if(dict.contains(nextWord)){ ret.add(nextWord); } } } return ret; } private String wordReplace(String word,int index,char c){ char[] newWord=word.toCharArray(); newWord[index]=c; return new String(newWord); }
二刷:
之前的单向BFS已经超时了,于是参考了双向BFS解法
双向BFS,复杂度更低,思想就是两个SET, 交替扩展,直到两个set有元素重合,即有一条可通路
/** * 双向BFS,复杂度更低,思想就是两个SET, 交替扩展,直到两个set有元素重合,即有一条可通路 */ public class WordLadder { public int ladderLength(String beginWord, String endWord, List<String> wordList) { int step = 0; Set<String> s1 = new HashSet<>(); Set<String> s2 = new HashSet<>(); Set<String> dict = new HashSet<>(); if (!wordList.contains(endWord)) return step; for (String word : wordList) dict.add(word); s1.add(beginWord); s2.add(endWord); while (!s1.isEmpty() && !s2.isEmpty()) { step++; if (s1.size() > s2.size()) swap(s1, s2); //每次都扩展容量小的那个set Set<String> tmpSet = new HashSet<>(); for (String word : s1) { for (String newWord : getNextWord(word)) { if (s2.contains(newWord)) return step + 1; if (!dict.contains(newWord)) continue; dict.remove(newWord); tmpSet.add(newWord); } } s1 = tmpSet; } return 0; } private List<String> getNextWord(String word) { List<String> res = new ArrayList<>(); res.add(word); for (int i = 0; i < word.length(); i++) { for (char c = ‘a‘; c <= ‘z‘; c++) { String newWord = replaceWord(word, i, c); res.add(newWord); } } return res; } private void swap(Object o1, Object o2) { Object tmp = o1; o1 = o2; o2 = tmp; } private String replaceWord(String word, int index, char c) { char[] newWord = word.toCharArray(); newWord[index] = c; return new String(newWord); } public static void main(String[] args) { WordLadder wordLadder = new WordLadder(); String[] strings = {"hot","dog"}; System.out.println(wordLadder.ladderLength("hot", "dog", Arrays.asList(strings))); } }
以上是关于LeetCode127. Word Ladder的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 127. Word Ladder ----- java
(Java) LeetCode 127. Word Ladder —— 单词接龙
LeetCode Top Interview Questions 127. Word Ladder (Java版; Medium)