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:
- You may assume all letters are in lowercase.
- You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
- If the order is invalid, return an empty string.
- There may be multiple valid order of letters, return any one of them is fine.
1 public class Solution { 2 public string AlienOrder(string[] words) { 3 if (words == null || words.Length == 0) return ""; 4 5 var sb = new StringBuilder(); 6 var ingree = new Dictionary<char, int>(); 7 8 // initialize ingree 9 foreach (var w in words) 10 { 11 for (int i = 0; i < w.Length; i++) 12 { 13 ingree[w[i]] = 0; 14 } 15 } 16 17 // build adjacent list and set ingree 18 var adjacentList = new Dictionary<char, HashSet<char>>(); 19 20 for (int i = 0; i < words.Length - 1; i++) 21 { 22 int k = 0, j = i + 1; 23 24 while (k < words[i].Length && k < words[j].Length) 25 { 26 if (words[i][k] != words[j][k]) 27 { 28 if (!adjacentList.ContainsKey(words[i][k])) 29 { 30 adjacentList[words[i][k]] = new HashSet<char>(); 31 } 32 33 if (!adjacentList[words[i][k]].Contains(words[j][k])) 34 { 35 ingree[words[j][k]]++; 36 adjacentList[words[i][k]].Add(words[j][k]); 37 } 38 39 break; 40 } 41 42 k++; 43 } 44 } 45 46 // bfs 47 var queue = new Queue<char>(); 48 49 foreach (var pair in ingree) 50 { 51 if (pair.Value == 0) 52 { 53 queue.Enqueue(pair.Key); 54 } 55 } 56 57 while (queue.Count > 0) 58 { 59 var c = queue.Dequeue(); 60 sb.Append(c); 61 62 if (adjacentList.ContainsKey(c)) 63 { 64 foreach (var item in adjacentList[c]) 65 { 66 ingree[item]--; 67 68 if (ingree[item] == 0) 69 { 70 queue.Enqueue(item); 71 } 72 } 73 } 74 } 75 76 return sb.Length == ingree.Count ? sb.ToString() : ""; 77 } 78 }