Skip to content

Commit 455fa55

Browse files
Alien Dictionary : Accepted
1 parent 76824bd commit 455fa55

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ My accepted leetcode solutions to some of the common interview problems.
6969
- [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium)
7070
- [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium)
7171
- [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium)
72+
- [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard)
7273

7374
#### [Design](problems/src/design)
7475

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package depth_first_search;
2+
3+
import java.util.*;
4+
5+
/**
6+
* Created by gouthamvidyapradhan on 02/12/2017.
7+
* There is a new alien language which uses the latin alphabet. However, the order among letters are unknown
8+
* to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the
9+
* rules of this new language. Derive the order of letters in this language.
10+
11+
Example 1:
12+
Given the following words in dictionary,
13+
14+
[
15+
"wrt",
16+
"wrf",
17+
"er",
18+
"ett",
19+
"rftt"
20+
]
21+
The correct order is: "wertf".
22+
23+
Example 2:
24+
Given the following words in dictionary,
25+
26+
[
27+
"z",
28+
"x"
29+
]
30+
The correct order is: "zx".
31+
32+
Example 3:
33+
Given the following words in dictionary,
34+
35+
[
36+
"z",
37+
"x",
38+
"z"
39+
]
40+
The order is invalid, so return "".
41+
42+
Note:
43+
You may assume all letters are in lowercase.
44+
You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
45+
If the order is invalid, return an empty string.
46+
There may be multiple valid order of letters, return any one of them is fine.
47+
48+
Solution: Build a graph with with character links and perform a topological sort. Topological sort can be
49+
performed only on a DAG hence if there is a cycle immediately return empty string
50+
51+
*/
52+
public class AlienDictionary {
53+
54+
private Map<Character, List<Character>> graph;
55+
private Set<Character> done;
56+
private Set<Character> visited;
57+
private Stack<Character> toposort;
58+
59+
/**
60+
* Main method
61+
* @param args
62+
* @throws Exception
63+
*/
64+
public static void main(String[] args) throws Exception{
65+
String[] words = {"z", "x", "z"};
66+
System.out.println(new AlienDictionary().alienOrder(words));
67+
}
68+
69+
public String alienOrder(String[] words) {
70+
graph = new HashMap<>();
71+
done = new HashSet<>();
72+
visited = new HashSet<>();
73+
toposort = new Stack<>();
74+
boolean[] A = new boolean[26];
75+
for(int i = 0; i < words.length - 1; i ++){
76+
for(int j = 0, l = Math.min(words[i].length(), words[i + 1].length()); j < l; j++){
77+
if(words[i].charAt(j) != words[i + 1].charAt(j)){
78+
graph.putIfAbsent(words[i].charAt(j), new ArrayList<>());
79+
graph.get(words[i].charAt(j)).add(words[i + 1].charAt(j));
80+
break;
81+
}
82+
}
83+
}
84+
85+
for(String w : words){
86+
for(int i = 0, l = w.length(); i < l; i++){
87+
A[w.charAt(i) - 'a'] = true;
88+
}
89+
}
90+
91+
for(char c : graph.keySet()){
92+
if(!done.contains(c)){
93+
if(!dfs(c)) return "";
94+
}
95+
}
96+
97+
StringBuilder sb = new StringBuilder();
98+
while(!toposort.isEmpty()){
99+
sb.append(toposort.pop());
100+
}
101+
102+
//Add remaining elements. This can come in any order.
103+
String result = sb.toString();
104+
StringBuilder remaining = new StringBuilder();
105+
for(int i = 0; i < 26; i ++){
106+
if(A[i]){
107+
char c = (char)(i + 'a');
108+
boolean found = false;
109+
for(char r : result.toCharArray()){
110+
if(r == c){
111+
found = true;
112+
break;
113+
}
114+
}
115+
if(!found){
116+
remaining.append(c);
117+
}
118+
}
119+
}
120+
return result.concat(remaining.toString().trim());
121+
}
122+
123+
/**
124+
* Dfs to toposort
125+
* @param u
126+
* @return
127+
*/
128+
private boolean dfs(char u){
129+
done.add(u);
130+
visited.add(u);
131+
List<Character> children = graph.get(u);
132+
if(children != null){
133+
for(char c : children){
134+
if(visited.contains(c)) return false; //check cycle
135+
if(!done.contains(c)){
136+
boolean status = dfs(c);
137+
if(!status) return false;
138+
}
139+
}
140+
}
141+
toposort.push(u);
142+
visited.remove(u);
143+
return true;
144+
}
145+
}

0 commit comments

Comments
 (0)