https://leetcode.com/problems/alien-dictionary/
单词按照一定次序排序,推导出原始顺序,典型的toposort,非常好的题目和重要的算法。
还是习惯炒肉说的基于indegree的bfs,学神的dfs总觉得别扭。当年老师教的静态链表太差了,太麻烦
有一个point就是里面不出现的单词不能出现,因此一定要mark,不然到时候都丢到queue里面取,因此可以用负数标记-1,因为度都是非负数,
然后图要去除环和重边,考虑到这点用hashmap edge[26]来存比较好
我写了两种写法,再生成图的时候,一种是从比较上下两个单词的第一次不同的单词来生成图,第二种是一个个枚举,然后每次还要取一个前缀串,似乎这个会多一个取串的系数,
第一种写法,还是这种好一些
class Solution {
public:
string alienOrder(vector<string>& dict) {
unordered_set<int> edge[26];
int deg[26];
memset(deg, -1 ,sizeof deg);
int maxlen=0;
for(auto s: dict){
maxlen=max((int)s.size(), maxlen);
for(auto se: s){
deg[se-'a']=0;
}
}
int cnt=0;//get chars count from input
for(int i=0;i<26;i++){
if(!deg[i]) cnt++;
}
for(int i=1;i<dict.size();i++){
for(int j=0; j < min(dict[i-1].size(), dict[i].size()); j++){
char from=dict[i-1][j], to=dict[i][j];
if(from != to){
if( !edge[from-'a'].count(to-'a')){
edge[from-'a'].insert(to-'a');
deg[to-'a']++;
break;
}
}
}
}
queue<int> q;
for(int i=0;i<26;i++){
if(!deg[i]) q.push(i);
}
string ans;
while(!q.empty()){
auto cur=q.front();q.pop();
ans.push_back(cur+'a');
for(auto e: edge[cur]){
if((--deg[e])==0) q.push(e);
}
}
return ans.size()==cnt ? ans : "";
}
} S;
第二种写法,只是生成图的部分差别较大
class Solution {
public:
string alienOrder(vector<string>& words) {
unordered_set<char> umch;
int maxlen=0;
for(auto se: words){
maxlen=max(maxlen, (int)se.size());
for(auto e: se){
umch.insert(e);
}
}
//mark in words and outof words char, as indegree 0 would be put in queue
int indeg[26];
memset(indeg, -1, sizeof indeg);
for(auto e: umch){
indeg[e-'a']=0;
}
int wordnum=words.size();
unordered_set<int> edge[26];
for(int i=0;i<maxlen;i++){
for(int j=0;j<wordnum;j++){
if(j-1>=0 && i<words[j].size() && i<words[j-1].size() && words[j][i] != words[j-1][i]
&& words[j-1].substr(0, i) == words[j].substr(0, i)){
int fromindex=words[j-1][i]-'a', toindex=words[j][i]-'a';
if( !edge[fromindex].count(toindex)){
edge[fromindex].insert(toindex);
indeg[toindex]++;
}
}
}
}
queue<int> q;
for(int i=0;i<26;i++){
if(!indeg[i]) q.push(i);
}
string ans;
while(!q.empty()){
auto cur=q.front();q.pop();
ans+=char('a'+cur);
for(auto e: edge[cur]){
if(!(--indeg[e])) q.push(e);
}
}
return ans.size() == umch.size() ? ans: "";
}
} S;