Fork me on GitHub

Alien Dictionary

Description

https://leetcode.com/problems/alien-dictionary/description/

Solution

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
class Solution {
public:
void extractRules(string& word1, string& word2, unordered_map<char, unordered_set<char>>& rules, unordered_map<char, int>& counter) {
int index = 0;
int bound = min(word1.size(), word2.size());
while(index < bound && word1[index] == word2[index]) {
++index;
}
if (index == bound) return;
char left = word1[index];
char right = word2[index];

if(rules[left].find(right) == rules[left].end()) {
rules[left].insert(right);
++counter[right];
}
}

void fillCharacter(unordered_map<char, int>& counter, vector<string>& words) {
for (string& word : words) {
for(int index = 0; index < word.size(); ++index) {
if (counter.count(word[index]) == 0) counter[word[index]] = 0;
}
}
}

string alienOrder(vector<string>& words) {
int size = words.size();
string ret;
if (size == 0) return ret;
unordered_map<char, unordered_set<char>> rules;
unordered_map<char, int> counter;

fillCharacter(counter, words);

for (int i = 0; i < size - 1; ++i){
for (int j = i + 1; j < size; ++j) {
string& word1 = words[i];
string& word2 = words[j];
extractRules(word1, word2, rules, counter);
}
}

queue<char> que;
for (auto iter = counter.begin(); iter != counter.end(); ++iter) {
if (iter->second == 0) {
ret += iter->first;
que.push(iter->first);
}
}


while (!que.empty()) {
char c = que.front();
que.pop();
unordered_set<char>& follows = rules[c];
for (char ch : follows) {
--counter[ch];
if (counter[ch] == 0) {
ret += ch;
que.push(ch);
}
}
}

for (auto& iter : counter) if (iter.second != 0) return string();

return ret;
}
};