Alien Dictionary

Graph, Topological Sorting

Hard

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:

Input:

[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]


Output: "wertf"

Example 2:

Input:

[
  "z",
  "x"
]


Output: "zx"

Example 3:

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.

Analysis & Solution

问题转化:alien单词字母表的先后顺序转化为依赖关系,那么这个字母表顺序就可以通过拓扑排序来得到。

Topological Sorting - BFS

通过input words建立邻接表,记录In-degree的数目,从in-degree为0的节点(字母)开始,放入Queue中,进行BFS。

接下来的就是用Kahn's aglorithm来做topological sort。

注意的要点:

  1. 如何将alien dictionary转化为邻接表

    1. 循环words[],words[i], words[i + 1]从头进行字符比较,如果出现不一样的字符 ch1 != ch2,说明存在lexicographical的关系(ch1 在 ch2之前),就可以记录ch2在ch1的邻接表中,并更新ch2的indegree加1。 因为从topological的角度,就是ch1依赖ch2,所以是ch2的indegree + 1。

  2. 如何初始化indegree的计数

    1. 有个tricky的地方在于如果用int indegree[]来记录,因为数组初始化默认都为0,所以不能仅仅凭借indegree[i - 'a']判断是否入度降为0,而需要额外辅助的set,记录在alien dictionary中出现过的字符。

    2. 或者用一个HashMap<Character, Integer> 进行记录,这样既可以计数indegree,也满足只记录alien dict出现的字符

  3. 何时更新indegree的计数

    1. 每次在queue中poll()之后,相当于要对这个ch对应的所有依赖的字符更新indegree,也就是在adjacency list邻接表中遍历对应的字符,再更新indegree的记录-1.

  4. 如何判断是否存在topological sorting

    1. 如果存在topological sorting,那么最后result的长度应该等于alien dictionary的key的个数

    2. 或者检测indegree hashmap中的每个字符indegree计数,如果有一个不为0,则说明不满足

代码:

Topological Sorting - DFS

by @yavinci:

The key to this problem:

A topological ordering is possible if and only if the graph has no directed cycles

Let's build a graph and perform a DFS. The following states made things easier.

  1. visited[i] = -1. Not even exist.

  2. visited[i] = 0. Exist. Non-visited.

  3. visited[i] = 1. Visiting.

  4. visited[i] = 2. Visited.

Another DFS - More Modularized

Last updated

Was this helpful?