269. Alien Dictionary

LeetCode

link
Topological Sorting using BFS, In-degree

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
class Solution {
public String alienOrder(String[] words) {
// Step 0: Create data structures and find all unique letters.
Map<Character, List<Character>> adjList = new HashMap<>();
Map<Character, Integer> inDegrees = new HashMap<>();
for (String word : words) {
for (char c : word.toCharArray()) {
inDegrees.put(c, 0);
adjList.put(c, new ArrayList<>());
}
}

// Step 1: Find all edges.
for (int i = 0; i < words.length - 1; i++) {
String word1 = words[i];
String word2 = words[i + 1];
// Check that word2 is not a prefix of word1.
if (word1.length() > word2.length() && word1.startsWith(word2)) {
return "";
}
// Find the first non match and insert the corresponding relation.
for (int j = 0; j < Math.min(word1.length(), word2.length()); j++) {
if (word1.charAt(j) != word2.charAt(j)) {
adjList.get(word1.charAt(j)).add(word2.charAt(j));
inDegrees.put(word2.charAt(j), inDegrees.get(word2.charAt(j)) + 1);
break;
}
}
}

// Step 2: Breadth-first search.
StringBuilder sb = new StringBuilder();
Queue<Character> queue = new LinkedList<>();
for (Character c : inDegrees.keySet()) {
if (inDegrees.get(c).equals(0)) {
queue.add(c);
}
}
while (!queue.isEmpty()) {
Character c = queue.poll();
sb.append(c);
for (Character next : adjList.get(c)) {
inDegrees.put(next, inDegrees.get(next) - 1);
if (inDegrees.get(next).equals(0)) {
queue.offer(next);
}
}
}
return sb.length()<inDegrees.size()?"":sb.toString();
}
}

DFS

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
class Solution {
private Map<Character, List<Character>> AdjList = new HashMap<>();
private Map<Character, Boolean> seen = new HashMap<>();
private StringBuilder output = new StringBuilder();

public String alienOrder(String[] words) {

// Step 0: Put all unique letters into AdjList as keys.
for (String word : words) {
for (char c : word.toCharArray()) {
AdjList.putIfAbsent(c, new ArrayList<>());
}
}

// Step 1: Find all edges and add reverse edges to AdjList.
for (int i = 0; i < words.length - 1; i++) {
String word1 = words[i];
String word2 = words[i + 1];
// Check that word2 is not a prefix of word1.
if (word1.length() > word2.length() && word1.startsWith(word2)) {
return "";
}
// Find the first non match and insert the corresponding relation.
for (int j = 0; j < Math.min(word1.length(), word2.length()); j++) {
if (word1.charAt(j) != word2.charAt(j)) {
AdjList.get(word1.charAt(j)).add(word2.charAt(j));
break;
}
}
}

// Step 2: DFS to build up the output list.
for (Character c : AdjList.keySet()) {
if (!dfs(c)) return "";
}

if (output.length() < AdjList.size()) {
return "";
}
return output.reverse().toString();
}

// Return true iff no cycles detected.
private boolean dfs(Character c) {
if (seen.getOrDefault(c,false)) {
return false;
}
seen.put(c, true);
for (Character next : AdjList.get(c)) {
if (!dfs(next)) return false;
}
seen.put(c, false);
if(output.indexOf(String.valueOf(c))<0) output.append(c);
return true;
}
}

0%