很好的参考:点击打开链接
此题关键是想到通过建图,再拓扑排序来解。思路一定要活。
每个不同的字母对就可以代表一条边。
public class Solution {
public String alienOrder(String[] words) {
StringBuilder order = new StringBuilder();
if (words == null) {
throw new IllegalArgumentException("");
}
if (words.length == 0) {
order.toString();
}
Map<Character/*char*/,Set<Character/*char*/>> map = new HashMap<>();
Map<Character/*char*/,Integer/*indegree*/> indegree = new HashMap<>();
intialize(words, map, indegree);
buildGraph(words, map, indegree);
sort(order, map, indegree);
//return order.toString();
return order.length() == indegree.size() ? order.toString() : "";
}
private void intialize(String[] words, Map<Character/*char*/,Set<Character/*char*/>> map, Map<Character/*char*/,Integer/*indegree*/> indegree) {
for (String word: words) {
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (!map.containsKey(c)) {
map.put(c, new HashSet<>());
}
if (!indegree.containsKey(c)) {
indegree.put(c, 0);
}
}
}
}
private void buildGraph(String[] words, Map<Character/*char*/,Set<Character/*char*/>> map, Map<Character/*char*/,Integer/*indegree*/> indegree) {
Set<String/*edge*/> edges = new HashSet<>();
for (int i = 0; i < words.length - 1; i++) {
String w1 = words[i];
String w2 = words[i + 1];
for (int j = 0; j < w1.length() && j < w2.length(); j++) {
char from = w1.charAt(j);
char to = w2.charAt(j);
if (from == to) {
continue;
}
String edge = from + "" + to;
if (!edges.contains(edge)) {
Set<Character> set = map.get(from);
set.add(to);
//int degree = indegree.get(from);
int degree = indegree.get(to);
degree = degree + 1;
//indegree.put(from, degree);
indegree.put(to, degree);
edges.add(edge);
break;
}
}
}
}
private void sort(StringBuilder order, Map<Character/*char*/,Set<Character/*char*/>> map, Map<Character/*char*/,Integer/*indegree*/> indegree) {
Queue<Character> queue = new LinkedList<>();
//for (Map.Entry entry: indegree.entrySet()) {
for (Map.Entry<Character/*char*/,Integer/*indegree*/> entry: indegree.entrySet()) {
if (entry.getValue() == 0) {
queue.offer(entry.getKey());
}
}
while (!queue.isEmpty()) {
char w = queue.poll();
order.append(w);
Set<Character> set = map.get(w);
for (char c: set) {
int degree = indegree.get(c);
if (degree != 0) {
degree = degree - 1;
if (degree == 0) {
queue.offer(c);
}
indegree.put(c, degree);
}
}
}
}
}