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.
UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
public int ladderLength(String beginWord, String endWord, List<String> list) {
HashSet<String> wordList = new HashSet<String>();
for(String s: list){
wordList.add(s);
}
Queue<String> queue = new LinkedList<String>();
queue.add(beginWord);
int level = 0;
while(!queue.isEmpty()){
int size = queue.size(); //BFS首先记录queue的大小
for(int i = 0; i < size; i++){
String cur = queue.remove();
if(cur.equals(endWord)){
return level + 1;
}
for(int j = 0; j < cur.length(); j++){
char[] word = cur.toCharArray();
for(char ch = 'a'; ch < 'z'; ch++){
word[j] = ch;
String check = new String(word);
if(wordList.contains(check)){
queue.add(check);
wordList.remove(check);
}
}
}
}
level++;//遍历完当层元素再加
}
return 0;
}
对于ladder II这种寻找path的题 如果求所有路径的是需要先bfs然后dfs,但是如果是只要一条最短路径,只需要一次bfs。具体来说在bfs的过程中,在把下一层节点i加入queue的时候,用一个map记录,key是下一层节点i的id, value是本层的节点id。这样到最后,就可以从结束点开始往前找parent,一直找到开头的点。因为加入queue的过程就是确定下一层点的parent的过程,所以每个点只进入queue一次,这个用set来保证。我说的这个只是针对输出一个最短path的解法,不过感觉现在确实好多面经是输出一条,个人感觉这样面试官更好看,输出那么多他也看不完~~
public ArrayList<String> wordLadder(HashSet<String> dict, String start, String end){
Queue<String> q = new LinkedList<String>();
q.offer(start);
ArrayList<String> result = new ArrayList<String>();
HashMap<String, String> map = new HashMap<String, String>();
while(!q.isEmpty()){
int size = q.size();
for(int i=0; i<size; i++){
String cur = q.remove();
if(q.equals(end)){
break;
}
for(int j=0; j<cur.length();j++){
char[] word = cur.toCharArray();
for(char ch='a'; ch<'z'; ch++){
word[j] = ch;
String newString = new String(word);
if(dict.contains(newString)){
map.put(newString, cur);
q.offer(newString);
dict.remove(newString);
}
}
}
}
}
String key = end;
String value = end;
result.add(0, key);
while(!value.equals(start)){
value = map.get(key);
result.add(0, value);
key = value;
}
return result;
}