题目:
There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.
Example 1:
Given the following words in dictionary,
[ "wrt", "wrf", "er", "ett", "rftt" ]
The correct order is: "wertf"
.
Example 2:
Given the following words in dictionary,
[ "z", "x" ]
The correct order is: "zx"
.
Example 3:
Given the following words in dictionary,
[ "z", "x", "z" ]
The order is invalid, so return ""
.
Note:
- You may assume all letters are in lowercase.
- You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
- If the order is invalid, return an empty string.
- There may be multiple valid order of letters, return any one of them is fine.
思路:
使用拓扑排序是这一道题目的正解。我们可以利用这道题目总结一下拓扑排序的实现框架:
1)定义两个哈希表,一个用来表示每次出现过的字符的入度,另一个来存一个字符指向的字符集合。
2)每次找出一个入度为0的字符,并且更新这个字符指向的字符集入度减1。如果在没有遍历完所有字符的情况下找不到入度为0的字符,那么说明没有合法的拓扑排序,返回“”。如果在一次遍历过程中出现了多个入度为0的字符,说明拓扑排序的解不唯一,任意选择其中一个就可以了。
代码:
class Solution {
public:
string alienOrder(vector<string>& words) {
if(words.size() == 0) {
return "";
}
unordered_map<char, int> indegree;
unordered_map<char, multiset<char>> hash;
for(auto word: words) {
for(auto ch: word) {
indegree[ch] = 0;
}
}
for(int i = 1; i < words.size(); i++) {
int k = 0, len1 = words[i-1].size(), len2 = words[i].size();
while(words[i-1][k] == words[i][k]) {
++k;
}
if(k >= min(len1, len2)) {
continue;
}
++indegree[words[i][k]];
hash[words[i - 1][k]].insert(words[i][k]);
}
string ret;
for(int i = 0; i < indegree.size(); i++) {
char ch = ' ';
for(auto val: indegree) {
if(!val.second) {
ch = val.first;
break;
}
}
if(ch == ' ') {
return "";
}
ret += ch;
--indegree[ch];
for(auto val: hash[ch]) {
--indegree[val];
}
}
return ret;
}
};