-
Notifications
You must be signed in to change notification settings - Fork 28
/
Alien_Dictionary.cpp
104 lines (98 loc) · 2.99 KB
/
Alien_Dictionary.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
class Solution {
public:
#define MAX 26
// works but visit same node twice in case like (1->2, 1->3, 3->2)
bool hasLoop(int node, vector<vector<int>>& adj, vector<bool>& marked) {
if(marked[node]) {
return true;
}
marked[node] = true;
for(int i = 0; i < (int)adj[node].size(); ++i) {
int neigh = adj[node][i];
if(hasLoop(neigh, adj, marked)) {
return true;
}
}
marked[node] = false;
return false;
}
#define WHITE 0
#define GRAY 1
#define BLACK 2
bool hasLoop2(int node, vector<vector<int>>& adj, vector<int>& color) {
if(color[node] == BLACK) {
return false;
}
if(color[node] == GRAY) {
return true;
}
color[node] = GRAY;
for(int i = 0; i < (int)adj[node].size(); ++i) {
int neigh = adj[node][i];
if(hasLoop2(neigh, adj, color)) {
return true;
}
}
color[node] = BLACK;
return false;
}
void topSortUtil(int node, vector<vector<int>>& adj, vector<bool>& visited, string& result) {
visited[node] = true;
for(int i = 0; i < (int)adj[node].size(); ++i) {
if(!visited[adj[node][i]]) {
topSortUtil(adj[node][i], adj, visited, result);
}
}
result += ('a' + node);
}
string topSort(vector<bool>& visited, vector<vector<int>>& adj) {
string result;
for(int i = 0; i < MAX; ++i) {
if(!visited[i]) {
topSortUtil(i, adj, visited, result);
}
}
reverse(result.begin(), result.end());
return result;
}
string alienOrder(vector<string>& words) {
string order;
vector<vector<int>> adj(MAX, vector<int>());
vector<bool> visited(MAX, true);
for(int i = 0; i < words.size(); ++i) {
for(int k = 0; k < words[i].length(); ++k) {
visited[words[i][k] - 'a'] = false;
}
}
for(int i = 0; i < words.size() - 1; ++i) {
string word1 = words[i];
string word2 = words[i + 1];
for(int j = 0, n = min(word1.length(), word2.length()); j < n; ++j) {
if(word1[j] != word2[j]) {
adj[word1[j] - 'a'].push_back(word2[j] - 'a');
break;
}
}
}
#if 0
vector<bool> marked(MAX, false);
for(int i = 0; i < MAX; ++i) {
if(!visited[i]) {
if(hasLoop(i, adj, marked)) {
return order;
}
}
}
#endif
vector<int> color(MAX, WHITE);
for(int i = 0; i < MAX; ++i) {
if(!visited[i]) {
if(hasLoop2(i, adj, color)) {
return order;
}
}
}
order = topSort(visited, adj);
return order;
}
};