public String alienOrder(String[] words) {
if (words == null || words.length == 0) {
Map<Character, Integer> inDegree = new HashMap<>();
Map<Character, Set<Character>> adjList = new HashMap<>();
for (String word : words) {
for (char c : word.toCharArray()) {
for (int i = 0; i < words.length - 1; i++) {
String curWord = words[i];
String nextWord = words[i + 1];
for (int j = 0; j < Math.min(curWord.length(), nextWord.length()); j++) {
char c1 = curWord.charAt(j);
char c2 = nextWord.charAt(j);
// We can only know the lexicographical order from the first two different words
Set<Character> set = adjList.getOrDefault(c1, new HashSet<>());
inDegree.put(c2, inDegree.get(c2) + 1);
// This is not lexicographically order
else if (j + 1 < curWord.length() && j + 1 == nextWord.length()) {
Queue<Character> queue = new LinkedList<>();
for (char key: inDegree.keySet()) {
if (inDegree.get(key) == 0) {
StringBuilder res = new StringBuilder();
while (!queue.isEmpty()) {
char curC = queue.remove();
if (adjList.containsKey(curC)) {
for (char nextC : adjList.get(curC)) {
inDegree.put(nextC, inDegree.get(nextC) - 1);
if (inDegree.get(nextC) == 0) {
return res.length() == inDegree.size() ? res.toString() : "";