-
Notifications
You must be signed in to change notification settings - Fork 0
/
AlienDictionary.java
124 lines (104 loc) · 3.69 KB
/
AlienDictionary.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
import java.util.*;
public class AlienDictionary {
/**
There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.
Example 1:
Input:
[
"wrt",
"wrf",
"er",
"ett",
"rftt"
]
Output: "wertf"
Example 2:
Input:
[
"z",
"x"
]
Output: "zx"
Example 3:
Input:
[
"z",
"x",
"z"
]
Output: ""
Explanation: The order is invalid, so return "".
Note:
You may assume all letters are in lowercase.
You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
If the order is invalid, return an empty string.
There may be multiple valid order of letters, return any one of them is fine.
*/
// Topological sort
public String alienOrder(String[] words) {
if (words == null || words.length == 0) return "";
HashMap<Character, Set<Character>> dependencies = new HashMap<>(); //<c1, Set<chars that depends on c1>>
int[] indegrees = new int[26];
int count = 0;
StringBuilder res = new StringBuilder();
for (String word : words) {
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (indegrees[c - 'a'] == 0) {
indegrees[c - 'a'] = 1;
dependencies.put(c, new HashSet<>());
count++;
}
}
}
// Build the graph
for (int i = 1; i < words.length; i++) {
char[] cWord1 = words[i - 1].toCharArray();
char[] cWord2 = words[i].toCharArray();
int len = Math.min(cWord1.length, cWord2.length);
for (int j = 0; j < len; j++) {
char c1 = cWord1[j];
char c2 = cWord2[j];
if (c1 != c2) {
if (!dependencies.get(c1).contains(c2)) {
indegrees[c2 - 'a']++;
dependencies.get(c1).add(c2);
}
break;
}
}
}
//Bfs the chars
Queue<Character> queue = new LinkedList<>();
do {
if (queue.isEmpty()) {
for (int i = 0; i < indegrees.length; i++) {
if (indegrees[i] == 1)
queue.add((char)('a' + i));
}
}
if (queue.isEmpty()) break;
char curC = queue.poll();
res.append(curC);
if (indegrees[curC - 'a'] != 1) return "";
indegrees[curC - 'a'] = 0;
Set<Character> charSet = dependencies.get(curC);
System.out.println(charSet);
for (char dC : charSet) {
indegrees[dC - 'a']--;
if (indegrees[dC - 'a'] == 1) queue.offer(dC);
if (indegrees[dC - 'a'] < 1) return "";
}
} while (!queue.isEmpty());
System.out.println(res);
if (res.length() != count) return "";
return res.toString();
}
// Test case : ["aac","aabb","aaba"]
// indegrees : a : 1, b : 1, c : 0
// dep : {c : b}, {b, a}
public static void main(String[] args) {
AlienDictionary a = new AlienDictionary();
a.alienOrder(new String[] {"wrt","wrf","er","ett","rftt","te"});
}
}