269. Alien Dictionary (H)
Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"Input: words = ["z","x"]
Output: "zx"Input: words = ["z","x","z"]
Output: ""
Explanation: The order is invalid, so return "".Solution:
Last updated
Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"Input: words = ["z","x"]
Output: "zx"Input: words = ["z","x","z"]
Output: ""
Explanation: The order is invalid, so return "".Last updated
class Solution {
public String alienOrder(String[] words) {
Map<Character, Set<Character>> graph = buildGraph(words);
if (graph == null) {
return "";
}
Map<Character, Integer> indegree = getIndegree(graph);
return topologicalSorting(graph, indegree);
}
public Map<Character, Set<Character>> buildGraph(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++)
{
graph.putIfAbsent(words[i].charAt(j), new HashSet<>());
}
}
// create edges
for(int i = 0; i< words.length-1; i++)
{
String word1 = words[i];
String word2 = words[i+1];
int index = 0;
int minLen = Math.min(word1.length(), word2.length());
while(index < minLen && index < minLen)
{
if(word1.charAt(index) != word2.charAt(index))
{
graph.get(word1.charAt(index)).add(word2.charAt(index));
break;
}
index++;
}
// Testcase: ["abc","ab"] ,expect output: ""
if(index == minLen && word1.length() > word2.length())
{
return null;
}
}
return graph;
}
public Map<Character, Integer> getIndegree(Map<Character, Set<Character>> graph)
{
Map<Character, Integer> indegree = new HashMap<>();
for(Character from : graph.keySet())
{
indegree.put(from, 0);
}
for(Character from : graph.keySet())
{
for(Character to : graph.get(from))
{
indegree.put(to, indegree.get(to) + 1);
}
}
return indegree;
}
public String topologicalSorting(Map<Character, Set<Character>> graph, Map<Character, Integer> indegree)
{
// as we should return the topo order with lexicographical order
// we should use PriorityQueue instead of a FIFO Queue
StringBuilder sb = new StringBuilder();
Queue<Character> queue = new PriorityQueue<>();
for(Character c : indegree.keySet())
{
if(indegree.get(c) == 0)
{
queue.offer(c);
}
}
while(!queue.isEmpty())
{
Character current = queue.poll();
sb.append(current);
for(Character adj : graph.get(current))
{
indegree.put(adj, indegree.get(adj)-1);
if(indegree.get(adj) == 0)
{
queue.offer(adj);
}
}
}
//最后还要判断排出来的拓扑序是不是有效的, 是不是所有的节点都遍历过了
//如果不是的话我们直接输出空串, 证明组成给定的这些单词的字母没有办法组成一个合理的拓扑序
if(sb.length() != indegree.size())
{
return "";
}
return sb.toString();
}
}