[LeetCode] 269. Alien Dictionary

There is a new alien language that uses the English alphabet. However, the order among the letters is unknown to you.

You are given a list of strings words from the alien language's dictionary, where the strings in words are sorted lexicographically by the rules of this new language.

Return a string of the unique letters in the new alien language sorted in lexicographically increasing order by the new language's rules. If there is no solution, return ""If there are multiple solutions, return any of them.

Example 1:

Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"

Example 2:

Input: words = ["z","x"]
Output: "zx"

Example 3:

Input: words = ["z","x","z"]
Output: ""
Explanation: The order is invalid, so return ""

Constraints:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] consists of only lowercase English letters.

火星词典。

现有一种使用字母的全新语言,这门语言的字母顺序与英语顺序不同。

假设,您并不知道其中字母之间的先后顺序。但是,会收到词典中获得一个 不为空的 单词列表。因为是从词典中获得的,所以该单词列表内的单词已经 按这门新语言的字母顺序进行了排序。

您需要根据这个输入的列表,还原出此语言中已知的字母顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/alien-dictionary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是拓扑排序,我这里给出的是BFS的解法。首先给每个牵涉到的字母都分别给一个入度1,同时需要计算这里一共牵涉到多少个不同的字母count。之后再次遍历input,这一次需要创建graph的边。创建的方式是用hashmap,分如下几个比较细节的步骤。

单词两两比较,发现第一个不同的字母之后,比如这个例子,

"wrt"和"wrf"

就把t当做key放入hashmap,map的value是一个hashset,再把f加入这个hashset,同时也把f的入度++,之后立即break(因为每两个单词之间其实只能最多得到两个字母之间的相对顺序)。照此遍历完所有的单词之后,根据入度表创建graph,还是把入度为1的字母加入queue。创建了graph之后,再来就是跟course schedule一样用BFS遍历每一条边,弹出queue的那一刻就将遍历到的字符append到结果集中;同时看这个字符是否在hashmap中,若在,也要去查看他对应的hashset里面有没有入度为1的字母,若有也要加入queue。最后如果res结果集的长度跟count不一致则返回空字符串。

时间O(V + E)

空间O(n) - 单词个数

Java实现

 1 class Solution {
 2     public static String alienOrder(String[] words) {
 3         // corner case
 4         if (words == null || words.length == 0) {
 5             return "";
 6         }
 7 
 8         // normal case
 9         StringBuilder res = new StringBuilder();
10         // 记录字典序
11         HashMap<Character, HashSet<Character>> map = new HashMap<>();
12         int[] degree = new int[26];
13         // 记录涉及到的字母的个数,最终输出的字典序的长度 == count
14         int count = 0;
15         for (String word : words) {
16             for (char c : word.toCharArray()) {
17                 if (degree[c - 'a'] == 0) {
18                     count++;
19                     degree[c - 'a'] = 1;
20                 }
21             }
22         }
23 
24         // 两两单词比较字母的不同
25         for (int i = 0; i < words.length - 1; i++) {
26             char[] cur = words[i].toCharArray();
27             char[] next = words[i + 1].toCharArray();
28             // corner case, 会有非法情况
29             // 如果某个单词出现在他的前缀之前,则说明这个排序是不合法的
30             // ["abc", "ab"]
31             if (cur.length > next.length && words[i].startsWith(words[i + 1])) {
32                 return "";
33             }
34 
35             // normal case, created the graph
36             int len = Math.min(cur.length, next.length);
37             for (int j = 0; j < len; j++) {
38                 if (cur[j] != next[j]) {
39                     if (!map.containsKey(cur[j])) {
40                         map.put(cur[j], new HashSet<>());
41                     }
42                     if (map.get(cur[j]).add(next[j])) {
43                         degree[next[j] - 'a']++;
44                     }
45                     break;
46                 }
47             }
48         }
49 
50         Queue<Character> queue = new LinkedList<>();
51         for (int i = 0; i < 26; i++) {
52             if (degree[i] == 1) {
53                 queue.offer((char) ('a' + i));
54             }
55         }
56 
57         while (!queue.isEmpty()) {
58             char cur = queue.poll();
59             res.append(cur);
60             if (map.containsKey(cur)) {
61                 for (char next : map.get(cur)) {
62                     if (--degree[next - 'a'] == 1) {
63                         queue.offer(next);
64                     }
65                 }
66             }
67         }
68         return res.length() == count ? res.toString() : "";
69     }
70 }

 

相关题目

207. Course Schedule

210. Course Schedule II

269. Alien Dictionary

310. Minimum Height Trees

953. Verifying an Alien Dictionary

LeetCode 题目总结

posted @ 2020-04-08 06:21  CNoodle  阅读(529)  评论(0编辑  收藏  举报