描述
有一种新的使用拉丁字母的外来语言。但是,你不知道字母之间的顺序。你会从词典中收到一个非空的单词列表,其中的单词在这种新语言的规则下按字典顺序排序。请推导出这种语言的字母顺序。
- 你可以假设所有的字母都是小写。
- 如果a是b的前缀且b出现在a之前,那么这个顺序是无效的。
- 如果顺序是无效的,则返回空字符串。
- 这里可能有多个有效的字母顺序,返回以正常字典顺序看来最小的。
在线评测地址:领扣题库官网
样例1
输入:["wrt","wrf","er","ett","rftt"]
输出:"wertf"
解释:
从 "wrt"和"wrf" ,我们可以得到 't'<'f'
从 "wrt"和"er" ,我们可以得到'w'<'e'
从 "er"和"ett" ,我们可以得到 get 'r'<'t'
从 "ett"和"rftt" ,我们可以得到 'e'<'r'
所以返回 "wertf"
样例2
输入:["z","x"]
输出:"zx"
解释:
从 "z" 和 "x",我们可以得到 'z' < 'x'
所以返回"zx"
解题思路
使用拓扑排序算法。 这个版本的实现当中,无需假设所有字母为小写字母。
源代码
class Solution {
public String alienOrder(String[] words) {
Map<Character, Set<Character>> graph = constructGraph(words);
if (graph == null) {
return "";
}
return topologicalSorting(graph);
}
private Map<Character, Set<Character>> constructGraph(String[] words) {
Map<Character, Set<Character>> graph = new HashMap<>();
// create nodes
for (int i = 0; i < words.length; i++) {
for (int j = 0; j < words[i].length(); j++) {
char c = words[i].charAt(j);
if (!graph.containsKey(c)) {
graph.put(c, new HashSet<Character>());
}
}
}
// create edges
for (int i = 0; i < words.length - 1; i++) {
int index = 0;
while (index < words[i].length() && index < words[i + 1].length()) {
if (words[i].charAt(index) != words[i + 1].charAt(index)) {
graph.get(words[i].charAt(index)).add(words[i + 1].charAt(index));
break;
}
index++;
}
if (index == Math.min(words[i].length(), words[i + 1].length())) {
if (words[i].length() > words[i + 1].length()) {
return null;
}
}
}
return graph;
}
private Map<Character, Integer> getIndegree(Map<Character, Set<Character>> graph) {
Map<Character, Integer> indegree = new HashMap<>();
for (Character u : graph.keySet()) {
indegree.put(u, 0);
}
for (Character u : graph.keySet()) {
for (Character v : graph.get(u)) {
indegree.put(v, indegree.get(v) + 1);
}
}
return indegree;
}
private String topologicalSorting(Map<Character, Set<Character>> graph) {
// as we should return the topo order with lexicographical order
// we should use PriorityQueue instead of a FIFO Queue
Map<Character, Integer> indegree = getIndegree(graph);
Queue<Character> queue = new PriorityQueue<>();
for (Character u : indegree.keySet()) {
if (indegree.get(u) == 0) {
queue.offer(u);
}
}
StringBuilder sb = new StringBuilder();
while (!queue.isEmpty()) {
Character head = queue.poll();
sb.append(head);
for (Character neighbor : graph.get(head)) {
indegree.put(neighbor, indegree.get(neighbor) - 1);
if (indegree.get(neighbor) == 0) {
queue.offer(neighbor);
}
}
}
if (sb.length() != indegree.size()) {
return "";
}
return sb.toString();
}
}
更多题解参考:九章官网solution