[LeetCode] 269. Alien Dictionary

火星词典。题意是给一堆字符串,请你输出其中字母之间的真正顺序(不是我们正常理解的26个字母的顺序)。例子,

Example 1:

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

Output: "wertf"

Example 2:

Input:
[
  "z",
  "x"
]

Output: "zx"

Example 3:

Input:
[
  "z",
  "x",
  "z"
] 

Output: "" 

Explanation: The order is invalid, so return "".

思路是拓扑排序,我这里给出的是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         if (words == null || words.length == 0)
 4             return "";
 5         StringBuilder res = new StringBuilder();
 6         HashMap<Character, Set<Character>> map = new HashMap<>();
 7         int[] degree = new int[26];
 8         int count = 0;
 9         for (String word : words) {
10             for (char c : word.toCharArray()) {
11                 if (degree[c - 'a'] == 0) {
12                     count++;
13                     degree[c - 'a'] = 1;
14                 }
15             }
16         }
17 
18         for (int i = 0; i < words.length - 1; i++) {
19             char[] cur = words[i].toCharArray();
20             char[] next = words[i + 1].toCharArray();
21             // corner case
22             // ["abc", "ab"]
23             if (cur.length > next.length && words[i].startsWith(words[i + 1])) {
24                 return "";
25             }
26 
27             // normal case, created the graph
28             int len = Math.min(cur.length, next.length);
29             for (int j = 0; j < len; j++) {
30                 if (cur[j] != next[j]) {
31                     if (!map.containsKey(cur[j])) {
32                         map.put(cur[j], new HashSet<>());
33                     }
34                     if (map.get(cur[j]).add(next[j])) {
35                         degree[next[j] - 'a']++;
36                     }
37                     break;
38                 }
39             }
40         }
41 
42         Queue<Character> queue = new LinkedList<>();
43         for (int i = 0; i < 26; i++) {
44             if (degree[i] == 1) {
45                 queue.offer((char) ('a' + i));
46             }
47         }
48 
49         while (!queue.isEmpty()) {
50             char c = queue.poll();
51             res.append(c);
52             if (map.containsKey(c)) {
53                 for (char ch : map.get(c)) {
54                     if (--degree[ch - 'a'] == 1) {
55                         queue.offer(ch);
56                     }
57                 }
58             }
59         }
60         if (res.length() != count) {
61             return "";
62         }
63         return res.toString();
64     }
65 }

猜你喜欢

转载自www.cnblogs.com/aaronliu1991/p/12657598.html
今日推荐