269. Alien Dictionary
Alien Dictionary
Solution
public class Solution {
public String alienOrder(String[] words) {
if (words == null || words.length < 1) return "";
if (words.length ==1) return words[0];
Map<Character, Node> map = new HashMap<>();
for (int i = 0; i < words.length; i++) {
String s1 = words[i];
for (int j = 0; j < s1.length(); j++) {
if (!map.containsKey(s1.charAt(j))) {
map.put(s1.charAt(j), new Node(s1.charAt(j)));
}
}
}
for (int i = 0; i <= words.length - 2; i++) {
String s1 = words[i];
String s2 = words[i + 1];
for (int j = 0; j < Math.min(s1.length(), s2.length()); j++) {
if (s1.charAt(j) != s2.charAt(j)) {
if (!map.containsKey(s1.charAt(j))) {
map.put(s1.charAt(j), new Node(s1.charAt(j)));
}
if (!map.containsKey(s2.charAt(j))) {
map.put(s2.charAt(j), new Node(s2.charAt(j)));
}
Node startNode = map.get(s1.charAt(j));
Node endNode = map.get(s2.charAt(j));
DirectedEdge directedEdge = new DirectedEdge(startNode, endNode);
startNode.addOutEdge(directedEdge);
endNode.addInEdge(directedEdge);
break;
}
}
}
StringBuffer sb = new StringBuffer();
int[] cyle = new int[1];
Map<Node, Boolean> onStack = new HashMap<>();
Map<Node, Boolean> onVisit = new HashMap<>();
for (Node node : map.values()) {
if (!onVisit.containsKey(node)) {
dfs(node, onStack, onVisit, sb, cyle);
}
}
if (cyle[0] == 1) {
return "";
} else {
return sb.reverse().toString();
}
}
private void dfs(Node currentNode, Map<Node, Boolean> onStack, Map<Node, Boolean> onVisit, StringBuffer sb, int[] cycle) {
if (cycle[0] == 1) {
return;
}
onStack.put(currentNode, true);
onVisit.put(currentNode, true);
for (DirectedEdge edge : currentNode.outEdges) {
Node nextNode = edge.end;
if (!onVisit.containsKey(nextNode)) {
dfs(nextNode, onStack, onVisit, sb, cycle);
} else if (onStack.containsKey(nextNode) && onStack.get(nextNode)) {
cycle[0] = 1;
return;
}
}
sb.append(currentNode.character);
onStack.put(currentNode, false);
}
private class Node {
Character character;
List<DirectedEdge> inEdges;
List<DirectedEdge> outEdges;
public Node(Character character) {
this.character = character;
this.inEdges = new ArrayList<>();
this.outEdges = new ArrayList<>();
}
public void addInEdge(DirectedEdge edge) {
for (int i = 0; i < inEdges.size(); i++) {
DirectedEdge current = inEdges.get(i);
if (current.start.character == edge.start.character && current.end.character == edge.end.character) {
return;
}
}
inEdges.add(edge);
}
public void addOutEdge(DirectedEdge edge) {
for (int i = 0; i < outEdges.size(); i++) {
DirectedEdge current = outEdges.get(i);
if (current.start.character == edge.start.character && current.end.character == edge.end.character) {
return;
}
}
outEdges.add(edge);
}
}
private class DirectedEdge {
Node start;
Node end;
public DirectedEdge(Node start, Node end) {
this.start = start;
this.end = end;
}
}
}Last updated