269. Alien Dictionary

There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.
Example 1:
Given the following words in dictionary,
[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]
The correct order is: "wertf".
Example 2:
Given the following words in dictionary,
[
  "z",
  "x"
]
The correct order is: "zx".
Example 3:
Given the following words in dictionary,
[
  "z",
  "x",
  "z"
]
The order is invalid, so return "".
Note:
  1. You may assume all letters are in lowercase.
  2. You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
  3. If the order is invalid, return an empty string.
  4. There may be multiple valid order of letters, return any one of them is fine.
Solution: DFS O(V+E)
1) create Graph with a set of character in given allen language().
2) for each adjacent words in given sorted array
  let the current pair words be word1 and word2. one by one compare characters of both words and find first mismatch character.
   create an edge from mismatched character of word1 to word2.
3) print the topologic sort of the above graph and determine whether there is a cycle is graph(add curStack)

public class Ex269AllienDictionary {

 public static void main(String[] args) {
  // TODO Auto-generated method stub

 }
 public class Graph{
  int v;
  Map<Character,LinkedList<Character>> adjs;
  HashSet<Character> chars;
//  LinkedList<Integer>[] adj;
  public Graph(String[] words) {
   
   adjs = new HashMap<Character, LinkedList<Character>>();
   chars = new HashSet<Character>();
   for(int i = 0; i < words.length; i++) {
    char[] cs = words[i].toCharArray();
    for(char c: cs) {
     chars.add(c);
    }
   }
   int vn = chars.size();
   this.v = vn;
   for(int i = 0; i < words.length - 1; i++) {
    String word1 = words[i];
    String word2 = words[i+1];
    for(int j = 0 ; j < Math.min(word1.length(), word2.length()); j++) {
     char c1 = word1.charAt(j);
     char c2 = word2.charAt(j);
     if(c1 != c2) {
  //if there is duplicate edge, visited will be marked, it's OK.
      LinkedList<Character> children = adjs.get(c1);
      if(children == null) {
       children = new LinkedList<Character>();
      }
      children.add(c2);
      break;//important
     }
    }
   }
  }
  
  public String topologicalSort() {
   Stack<Character> s = new Stack<Character>();
   Map<Character,Boolean> visitedMap = new HashMap<Character,Boolean>();
   Map<Character,Boolean> curStack = new HashMap<Character,Boolean>();
   StringBuilder res = new StringBuilder();
   Iterator<Character> it = chars.iterator();
   Boolean isCylic = false;
   if(it.hasNext()) {
    char c = it.next();
    Boolean visited = visitedMap.get(c);
    if(visited == null || !visited) {
     isCylic = this.sortUtil(c, s, visitedMap,curStack);
    }

   }
   while(!isCylic && !s.isEmpty()) {
    res.append(s.pop());
   }
   return res.toString(); 
  }
  //return isCylic
  public boolean sortUtil(char c, Stack<Character> s, 
                       Map<Character,Boolean> visitedMap,Map<Character,Boolean> curStack) {
   visitedMap.put(c, true);
   curStack.put(c, true);
   LinkedList<Character> adj = this.adjs.get(c);
   for(Character to: adj) {
    Boolean toVisited = visitedMap.get(to);
    Boolean isAncentor = curStack.get(to);
    if(isAncentor) {
     return true;
    }else if(toVisited == null || !toVisited) {
     if(sortUtil(to,s,visitedMap,curStack)) {
      return true;
     }
    }
   }
   s.push(c);
   curStack.put(c, false);
   return false;
  }
 }
 public String alienOrder(String[] words) {

  
  Graph g = new Graph(words);
  String res = g.topologicalSort();
  return res;
  
 }
}



Comments

Popular posts from this blog

MockInterview:785. Is Graph Bipartite?

geeksforgeeks:findFind zeroes to be flipped so that number of consecutive 1’s is maximized

94.Binary Tree Inorder Traversal