269. Alien Dictionary
问题描述:
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:
Input:
[
"wrt",
"wrf",
"er",
"ett",
"rftt"
]
Output: "wertf"
Example 2:
Input:
[
"z",
"x"
]
Output: "zx"
Example 3:
Input: [ "z", "x", "z" ] Output:""
Explanation: 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.构建图:
对字典中出现的每一个字母,初始化它的入度为0.
对字典中的每一个单词,我们用它与它后面一个单词相比较,找到第一个不相等的字母,将words[i][j]指向words[i+1][j](加入到邻接链表中),同时增加words[i+1][j]的入度。
2.拓扑排序:
现将入度为0的放入队列中
取出队首元素放入返回字符串中,根据邻接链表将其邻接点的入度减1,若此时邻接点的入度为0,则将该点加入队列。
3.检查是否有环:
若返回字符串的长度不等于indegree中节点的长度,则说明有环,清空ret。
代码:
class Solution { public: string alienOrder(vector<string>& words) { string ret; unordered_map<char, vector<char>> graph; unordered_map<char, int> in_degree; for(auto w : words){ for(auto c : w){ in_degree[c] = 0; } } for(int i = 0; i < words.size()-1; i++){ if(words[i][0] != words[i+1][0]){ graph[words[i][0]].push_back(words[i+1][0]); in_degree[words[i+1][0]]++; }else{ int j = 0; int len = min(words[i].size(), words[i+1].size()); while(j < len && words[i][j] == words[i+1][j]) j++; if(j != len){ graph[words[i][j]].push_back(words[i+1][j]); in_degree[words[i+1][j]]++; } } } queue<char> q; for(auto p : in_degree){ if(p.second == 0) q.push(p.first); } while(!q.empty()){ char cur = q.front(); q.pop(); ret.push_back(cur); if(graph.count(cur)){ for(auto c : graph[cur]){ in_degree[c]--; if(in_degree[c] == 0) q.push(c); } } } if(ret.size() != in_degree.size()) ret.clear(); return ret; } };