Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
Given: start =
"hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
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.
Solution:
We first preprocess the dictionary creating a hashmap that contains the list of neighbor words for each one.Then we apply BFS keeping a set of the nodes already visited.
public class Solution { public int ladderLength(String start, String end, HashSet<String> dict) { HashMap<String, ArrayList<String>> neighbors = new HashMap<String, ArrayList<String>>(); for(String word: dict) { ArrayList<String> listNeighbors = new ArrayList<String>(); StringBuilder attempt = new StringBuilder(word); for(int i=0; i<word.length(); i++) { for(char letter='a'; letter<='z'; letter++) { if(word.charAt(i)==letter) continue; attempt.setCharAt(i,letter); if(dict.contains(attempt.toString())) listNeighbors.add(attempt.toString()); } attempt.setCharAt(i,word.charAt(i)); } neighbors.put(word,listNeighbors); } final String newLevel = "#"; ArrayDeque<String> queue = new ArrayDeque<String>(); HashSet<String> usedWords = new HashSet<String>(); queue.add(start); queue.add(newLevel); usedWords.add(start); int levels = 1; while(!queue.isEmpty()) { String actual = queue.remove(); if(actual.equals(end)) return levels; if(actual.equals(newLevel)) { if(queue.isEmpty() || queue.peek().equals(newLevel)) return 0; queue.add(newLevel); levels++; } else { for(String neighbor: neighbors.get(actual)) { if(!usedWords.contains(neighbor)) { queue.add(neighbor); usedWords.add(neighbor); } } } } return 0; } }
No comments :
Post a Comment