Problem
Given two words of equal length that are in a dictionary, write a method to transform one word into another word by changing only one letter at a time. The new word you get in each step must be in the dictionary.
EXAMPLE
Input: DAMP, LIKE
Output: DAMP -> LAMP -> LIMP -> LIME -> LIKE
Solution
Try thinking this problem in terms of graphs: Consider all words in a dictionary as vertices, and insert an edge between each two vertices that differ by only one letter. The output is a well-known object in the graph, and you probably already know an algorithm to solve the problem.The output is a path in the graph, and the question is solved by finding a path. A breadth-first search (BFS) or Dijkstra's algorithm solve the problem elegantly.
Java code
public static List<String> transform(String src, String des,
Set<String> dictionary) {
Queue<String> Q = new LinkedList<String>();
Set<String> visited = new HashSet<String>();
Map<String, String> routes = new HashMap<String, String>();
Q.add(src);
visited.add(src);
while (!Q.isEmpty()) {
String t = Q.poll();
if (t.equals(des)) {
LinkedList<String> list = new LinkedList<String>();
while (t != null) {
list.add(0, t);
t = routes.get(t);
}
return list;
}
for (String o : getAllTransformations(t, dictionary)) {
if (!visited.contains(o)) {
visited.add(o);
Q.add(o);
routes.put(o, t);
}
}
}
return null;
}
private static List<String> getAllTransformations(String src,
Set<String> dictionary) {
List<String> results = new LinkedList<String>();
for (int i = 0; i < src.length(); ++i) {
for (char c = 'A'; c <= 'Z'; ++c) {
String newStr = src.substring(0, i) + c + src.substring(i + 1);
if (!src.equals(newStr) && dictionary.contains(newStr))
results.add(newStr);
}
}
return results;
}
Thanks.
References







0 comments:
Post a Comment