classSolution{public:stringalienOrder(vector<string>&words){unordered_map<char,unordered_set<char>>graph;vector<int>inDegree(26);buildGraph(graph,words,inDegree);returntopology(graph,inDegree);}private:voidbuildGraph(unordered_map<char,unordered_set<char>>&graph,constvector<string>&words,vector<int>&inDegree){// Create node for each character in each wordfor(conststring&word:words)for(constcharc:word)if(!graph.count(c))graph[c]=unordered_set<char>();for(inti=1;i<words.size();++i){conststring&first=words[i-1];conststring&second=words[i];constintlength=min(first.length(),second.length());for(intj=0;j<length;++j){constcharu=first[j];constcharv=second[j];if(u!=v){if(!graph[u].count(v)){graph[u].insert(v);++inDegree[v-'a'];}break;// Later characters' order are meaningless}// First = "ab", second = "a" -> invalidif(j==length-1&&first.length()>second.length()){graph.clear();return;}}}}stringtopology(unordered_map<char,unordered_set<char>>&graph,vector<int>&inDegree){strings;queue<char>q;for(constauto&[c,_]:graph)if(inDegree[c-'a']==0)q.push(c);while(!q.empty()){constcharu=q.front();q.pop();s+=u;for(constcharv:graph[u])if(--inDegree[v-'a']==0)q.push(v);}// Words = ["z", "x", "y", "x"]returns.length()==graph.size()?s:"";}};
classSolution{publicStringalienOrder(String[]words){Map<Character,Set<Character>>graph=newHashMap<>();int[]inDegree=newint[26];buildGraph(graph,words,inDegree);returntopology(graph,inDegree);}privatevoidbuildGraph(Map<Character,Set<Character>>graph,String[]words,int[]inDegree){// Create node for each character in each wordfor(finalStringword:words)for(finalcharc:word.toCharArray())graph.putIfAbsent(c,newHashSet<>());for(inti=1;i<words.length;++i){finalStringfirst=words[i-1];finalStringsecond=words[i];finalintlength=Math.min(first.length(),second.length());for(intj=0;j<length;++j){finalcharu=first.charAt(j);finalcharv=second.charAt(j);if(u!=v){if(!graph.get(u).contains(v)){graph.get(u).add(v);++inDegree[v-'a'];}break;// Later characters' order are meaningless}// First = "ab", second = "a" -> invalidif(j==length-1&&first.length()>second.length()){graph.clear();return;}}}}privateStringtopology(Map<Character,Set<Character>>graph,int[]inDegree){StringBuildersb=newStringBuilder();Queue<Character>q=graph.keySet().stream().filter(c->inDegree[c-'a']==0).collect(Collectors.toCollection(ArrayDeque::new));while(!q.isEmpty()){finalcharu=q.poll();sb.append(u);for(finalcharv:graph.get(u))if(--inDegree[v-'a']==0)q.offer(v);}// Words = ["z", "x", "y", "x"]returnsb.length()==graph.size()?sb.toString():"";}}
classSolution:defalienOrder(self,words:List[str])->str:graph={}inDegree=[0]*26self._buildGraph(graph,words,inDegree)returnself._topology(graph,inDegree)def_buildGraph(self,graph:Dict[chr,Set[chr]],words:List[str],inDegree:List[int])->None:# Create node for each character in each wordforwordinwords:forcinword:ifcnotingraph:graph[c]=set()forfirst,secondinzip(words,words[1:]):length=min(len(first),len(second))forjinrange(length):u=first[j]v=second[j]ifu!=v:ifvnotingraph[u]:graph[u].add(v)inDegree[ord(v)-ord('a')]+=1break# Later characters' order are meaningless# First = 'ab', second = 'a' . invalidifj==length-1andlen(first)>len(second):graph.clear()returndef_topology(self,graph:Dict[chr,Set[chr]],inDegree:List[int])->str:s=''q=deque()forcingraph:ifinDegree[ord(c)-ord('a')]==0:q.append(c)whileq:u=q.pop()s+=uforvingraph[u]:inDegree[ord(v)-ord('a')]-=1ifinDegree[ord(v)-ord('a')]==0:q.append(v)# Words = ['z', 'x', 'y', 'x']returnsiflen(s)==len(graph)else''