【拓扑排序】
class Solution {
public String alienOrder(String[] words) {
int n = words.length, i, j, m;
Set<String> set = new HashSet();
String pre = words[0];
Set<Character> cnt = new HashSet();
Set<Character> all = new HashSet();
for(var w: words){
m = w.length();
for(i = 0; i < m; i++){
all.add(w.charAt(i));
}
}
for(i = 1; i < n; i++){
String str = words[i];
m = Math.min(str.length(), pre.length());
int f = 0;
for(j = 0; j < m; j++){
if(pre.charAt(j) != str.charAt(j)){
set.add("" + pre.charAt(j) + str.charAt(j));
cnt.add(pre.charAt(j));
cnt.add(str.charAt(j));
f = 1;
break;
}
}
if(f == 0 && pre.length() > str.length()) return "";
pre = str;
}
// if(set.size() == 0 && all.size() > 1) return "";
Map<Character, Integer> map = new HashMap();
for(var c: set){
if(!map.containsKey(c.charAt(0))) map.put(c.charAt(0), 0);
map.put(c.charAt(1), map.getOrDefault(c.charAt(1), 0) + 1);
}
// map.forEach((k, v) -> {System.out.println(k + " " + v);});
int flag = 1;
String ans = "";
while(flag == 1){
flag = 0;
for(var key: map.keySet()){
if(map.get(key) == 0){
flag = 1;
map.put(key, -1);
ans += key;
for(var str: set){
if(str.charAt(0) == key){
map.put(str.charAt(1), map.get(str.charAt(1)) - 1);
}
}
}
}
}
// System.out.println(ans);
if(ans.length() != cnt.size()) return "";
for(var c: all){
if(!cnt.contains(c)) ans += c;
}
return ans;
}
}