-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathProblem1634.java
126 lines (106 loc) · 3.62 KB
/
Problem1634.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
/**
* This problem was asked by Facebook.
*
* Given a start word, an end word, and a dictionary of valid words, find the shortest
* transformation sequence from start to end such that only one letter is changed at each
* step of the sequence, and each transformed word exists in the dictionary. If there is no
* possible transformation, return null. Each word in the dictionary have the same length as
* start and end and is lowercase.
*
* For example, given start = "dog", end = "cat", and dictionary = {"dot", "dop", "dat",
* "cat"}, return ["dog", "dot", "dat", "cat"].
*
* Given start = "dog", end = "cat", and dictionary = {"dot", "tod", "dat", "dar"}, return
* null as there is no possible transformation from dog to cat.
*/
public class Problem1634 {
public static void main(String[] args) {
String start = "dog";
String end = "cat";
String[] map = {
"dot", "dop",
"dat", "cat"
};
String[] paths = getTransformationPath(start, end, map);
System.out.println(Arrays.deepToString(paths));
}
public static String[] getTransformationPath(String start, String end, String[] map) {
String[] transformationPath = null;
// Keeping all items not yet added a child of any node
Queue<String> remaining = new LinkedList<>();
for (String s: map) {
remaining.add(s);
}
// To perform BFS search
Queue<SNode> bfs = new LinkedList<>();
// Adding first root node
bfs.add(new SNode(start));
SNode curr;
for (curr = bfs.poll(); curr != null && !curr.data.equals(end); curr = bfs.poll()) {
int remainingCount = remaining.size();
String r;
while (remainingCount > 0) {
r = remaining.poll();
int diff = getCharacterDiff(curr.data, r);
if (diff == 1) {
// Make a child of current node and also add to BFS search list
// We make it a child so we can trace back to the parent to build
// the path.
SNode n = new SNode(r, curr);
bfs.add(n);
} else {
remaining.add(r);
}
remainingCount--;
}
}
if (curr.data.equals(end)) {
transformationPath = stringifyPath(curr);
}
return transformationPath;
}
public static int getCharacterDiff(String s1, String s2) {
if (s1.length() != s2.length()){
throw new IllegalArgumentException("Cannot utilize two strings with different lengths");
}
int diff = 0;
for (int i = 0; i < s1.length(); i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
diff++;
}
}
return diff;
}
public static String[] stringifyPath(SNode node) {
String[] path = new String[node.height() + 1];
for (; node != null; node = node.parent) {
path[node.height()] = node.data;
}
return path;
}
}
class SNode {
SNode parent;
String data;
public SNode(String data) {
this.data = data;
}
public SNode(String data, SNode parent) {
this(data);
this.parent = parent;
}
public int height() {
if (this.parent == null) {
return 0;
}
return this.parent.height() + 1;
}
public String toString() {
return this.data;
}
}