https://leetcode.com/problems/alien-dictionary/
1.words数组转换成图
2.对图进行拓扑排序
注意:
所有元素都要加到邻接表中;
入度不要重复统计;
拓扑排序可以非递归或者dfs;
非递归:
class Solution {
public:
string alienOrder(vector<string>& words) {
unordered_map<char, unordered_set<char> > g;
unordered_map<char, int> incount;
string res;
//init
for(int i = 0; i < words.size(); i++) {
for(int j = 0; j < words[i].size(); j++) {
g.insert(make_pair(words[i][j],unordered_set<char>()));
incount.insert(make_pair(words[i][j],0));
}
}
//process words
for(int i = 1; i < words.size(); i++) {
int minlen = min(words[i-1].size(), words[i].size());
for(int j = 0; j < minlen; j++) {
if(words[i-1][j] != words[i][j]) {
if(g[words[i-1][j]].find(words[i][j]) == g[words[i-1][j]].end()) {
g[words[i-1][j]].insert(words[i][j]);
incount[words[i][j]]++;
}
break;
}
}
}
//topology
int count = incount.size();
while(count--) {
bool found = false;
for(auto &i : incount) {
if(i.second == 0) {
i.second = -1;
found = true;
res += i.first;
for(auto &j : g[i.first]) {
incount[j]--;
}
break;
}
}
if(found == false) { //cycle
return "";
}
}
return res;
}
};
dfs:
rec用来判断是否有环;
visited用来记录是否访问过;
dfs的结果是逆序的拓扑;
class Solution {
bool dfs (char c, unordered_map<char, unordered_set<char> > &g, unordered_set<char> &visited, unordered_set<char> &rec, string &res) {
if(visited.find(c) != visited.end()) return true;
if(rec.find(c) != rec.end()) return false;
rec.insert(c);
for(auto &i:g[c]) {
if(!dfs(i,g,visited,rec,res))
return false;
}
rec.erase(c);
visited.insert(c);
res += c;
return true;
}
string topo(unordered_map<char, unordered_set<char> > &g){
string res;
unordered_set<char> visited;
unordered_set<char> rec;
for(auto &i:g) {
if(!dfs(i.first, g,visited,rec,res))
return "";
}
reverse(res.begin(),res.end());
return res;
}
public:
string alienOrder(vector<string>& words) {
unordered_map<char, unordered_set<char> > g;
unordered_map<char, int> incount;
string res;
//init
for(int i = 0; i < words.size(); i++) {
for(int j = 0; j < words[i].size(); j++) {
g.insert(make_pair(words[i][j],unordered_set<char>()));
incount.insert(make_pair(words[i][j],0));
}
}
//process words
for(int i = 1; i < words.size(); i++) {
int minlen = min(words[i-1].size(), words[i].size());
for(int j = 0; j < minlen; j++) {
if(words[i-1][j] != words[i][j]) {
if(g[words[i-1][j]].find(words[i][j]) == g[words[i-1][j]].end()) {
g[words[i-1][j]].insert(words[i][j]);
incount[words[i][j]]++;
}
break;
}
}
}
return topo(g);
}
};