//https://leetcode.cn/problems/Jf1JuT/
const int N=26,M=110;
class Solution {
private:
int head[N],Next[M],to[M],cnt;
int indegree[N];
int h,t;
int q[N];
string ans;
void addEdge(int u,int v){
Next[cnt]=head[u];
to[cnt]=v;
head[u]=cnt++;
}
void build(){
h=t=0;
cnt=1;
memset(indegree,-1,sizeof indegree);
memset(head,0,sizeof head);
}
bool topoSort(){
int kinds=0;
for(int i=0;i<26;i++){
if(indegree[i]!=-1) kinds++;
if(indegree[i]==0) q[t++]=i;
}
int fill=0;
while(h<t){
int u=q[h++];
ans.push_back(u+'a'),fill++;
for(int ei=head[u],v;ei;ei=Next[ei]){
v=to[ei];
if(--indegree[v]==0) q[t++]=v;
}
}
return fill==kinds;
}
public:
string alienOrder(vector<string>& words) {
build();
for(int i=0;i<words.size();i++){
for(int j=0;j<words[i].size();j++){
indegree[words[i][j]-'a']=0;
}
}
for(int i=0;i<words.size()-1;i++){
string cur=words[i],nxt=words[i+1];
int len=min(cur.size(),nxt.size());
int j=0;
for(;j<len;j++){
if(cur[j]!=nxt[j]){
addEdge(cur[j]-'a',nxt[j]-'a');
indegree[nxt[j]-'a']++;
break;
}
}
if(j<cur.size()&&j==nxt.size()) return "";
}
if(!topoSort()) ans.clear();
return ans;
}
};