从现在开始每天至少刷一道题。
题库:lintcode
有些题目链接打不开,需要权限,那大家就去九章算法参考答案里找找。
892. Alien Dictionary
题目链接
难度:hard
算法:拓扑排序
时间复杂度:这道题的时间复杂度我也有点纠结,在建图过程中先循环words,然后嵌套循环每个单词中的字符,其中用了if语句提早终止循环。如果if语句不算基本操作,那么这里的时间复杂度就是O(max(V, E))。如果if语句算作基本操作,那么时间复杂度最坏就是O(MN),M表示单词数,N表示最长的单词字符数。计算indegree和拓扑排序过程都是O(V + E)
空间复杂度:O(V + E), 建图用的内存
解题思路
思路挺简单,但是实现有点难度。先建图,然后计算每个顶点的入度indegree,最后用拓扑排序。
注意
- 图的顶点是words里面的不重复字符
- 图的边是比较前后单词的首个不相等的字符,比如"wrt"and"wrf" ,we can get ‘t’<‘f’
- 图可以通过一个
Map<Character, Set<Character>>
实现 - 如果有多个排序结果,取字母表排序结果。所以这里的队列不用linkedlist,而是优先队列priorityqueue实现最小堆。
解法
public class Solution {
/**
* @param words: a list of words
* @return: a string which is correct order
*/
public String alienOrder(String[] words) {
// Write your code here
//create graph ??
Map<Character, Set<Character>> graph = createGraph(words);
if(graph == null){
return "";
}
//compute indegree in graph O(V + E)
Map<Character, Integer> indegree = computeIndegree(graph);
//topological sorting O(V + E)
return topologicalSorting(graph, indegree);
}
private Map<Character, Set<Character>> createGraph(String[] words){
Map<Character, Set<Character>> graph = new HashMap<>();
//create node
for(int i=0;i<words.length;i++){
//n
String word = words[i];
for(int j=0;j<word.length();j++){
//m
if(!graph.containsKey(word.charAt(j))){
//m
graph.put(word.charAt(j), new HashSet<Character>()); //v
}
}
}
//create edges
for(int i=0;i<words.length - 1;i++){
//n
int j = 0;