File tree 2 files changed +17
-13
lines changed
lcof2/剑指 Offer II 114. 外星文字典
solution/0200-0299/0269.Alien Dictionary
2 files changed +17
-13
lines changed Original file line number Diff line number Diff line change 38
38
<pre >
39
39
<strong >输入:</strong >words = [" ; z" ; ," ; x" ; ," ; z" ; ]
40
40
<strong >输出:</strong >" ;" ;
41
- <strong >解释:</strong >不存在合法字母顺序,因此返回 < code > " ;" ; 。</ code >
41
+ <strong >解释:</strong >不存在合法字母顺序,因此返回 " ;" ; 。
42
42
</pre >
43
43
44
44
<p >  ; </p >
59
59
60
60
<!-- 这里可写通用的实现逻辑 -->
61
61
62
- 用 g 数组记录在火星字典中的字母先后关系, ` g[i][j] = true ` 表示字母 ` i + 'a' ` 在字母 ` j + 'a' ` 的前面;用 s 数组记录当前字典出现过的字母,cnt 表示出现过的字母数。
62
+ ** 方法一:拓扑排序 + BFS **
63
63
64
- 一个很简单的想法是遍历每一个单词,比较该单词和其后的所有单词,把所有的先后关系更新进 g 数组,这样遍历时间复杂度为 ` O(n^3) ` ;但是我们发现其实比较相邻的两个单词就可以了,比如 ` a < b < c ` 则比较 ` a < b ` 和 ` b < c ` , a 和 c 的关系便确定了。因此算法可以优化成比较相邻两个单词,时间复杂度为 ` O(n²) ` 。
64
+ 用数组 $g$ 记录在火星字典中的字母先后关系,$g[ i] [ j ] = true$ 表示字母 $i + 'a'$ 在字母 $j + 'a'$ 的前面;用数组 $s$ 记录当前字典出现过的字母,$cnt$ 表示出现过的字母数。
65
+
66
+ 一个很简单的想法是遍历每一个单词,比较该单词和其后的所有单词,把所有的先后关系更新进数组 $g$,这样遍历时间复杂度为 $O(n^3)$;但是我们发现其实比较相邻的两个单词就可以了,比如 $a < b < c$ 则比较 $a < b$ 和 $b < c$, $a$ 和 $c$ 的关系便确定了。因此算法可以优化成比较相邻两个单词,时间复杂度为 $O(n²)$。
65
67
66
68
出现矛盾的情况:
67
69
68
- - ` g[i][j] = g[j][i] = true ` ;
70
+ - $ g[ i] [ j ] $ = $ g[ j] [ i ] $ = $ true$ ;
69
71
- 后一个单词是前一个单词的前缀;
70
- - 在拓扑排序后 ans 的长度小于统计到的字母个数。
72
+ - 在拓扑排序后 $ ans$ 的长度小于统计到的字母个数。
71
73
72
74
拓扑排序:
73
75
74
76
- 统计所有出现的字母入度;
75
- - 将所有入度为 0 的字母加入队列;
76
- - 当队列不空,出队并更新其他字母的入度,入度为 0 则入队,同时出队时将当前字母加入 ans 的结尾;
77
+ - 将所有入度为 $0$ 的字母加入队列;
78
+ - 当队列不空,出队并更新其他字母的入度,入度为 $0$ 则入队,同时出队时将当前字母加入 $ ans$ 的结尾;
77
79
- 得到的便是字母的拓扑序,也就是火星字典的字母顺序。
78
80
79
81
<!-- tabs:start -->
Original file line number Diff line number Diff line change 57
57
58
58
<!-- 这里可写通用的实现逻辑 -->
59
59
60
- 用 g 数组记录在火星字典中的字母先后关系, ` g[i][j] = true ` 表示字母 ` i + 'a' ` 在字母 ` j + 'a' ` 的前面;用 s 数组记录当前字典出现过的字母,cnt 表示出现过的字母数。
60
+ ** 方法一:拓扑排序 + BFS **
61
61
62
- 一个很简单的想法是遍历每一个单词,比较该单词和其后的所有单词,把所有的先后关系更新进 g 数组,这样遍历时间复杂度为 ` O(n^3) ` ;但是我们发现其实比较相邻的两个单词就可以了,比如 ` a < b < c ` 则比较 ` a < b ` 和 ` b < c ` , a 和 c 的关系便确定了。因此算法可以优化成比较相邻两个单词,时间复杂度为 ` O(n²) ` 。
62
+ 用数组 $g$ 记录在火星字典中的字母先后关系,$g[ i] [ j ] = true$ 表示字母 $i + 'a'$ 在字母 $j + 'a'$ 的前面;用数组 $s$ 记录当前字典出现过的字母,$cnt$ 表示出现过的字母数。
63
+
64
+ 一个很简单的想法是遍历每一个单词,比较该单词和其后的所有单词,把所有的先后关系更新进数组 $g$,这样遍历时间复杂度为 $O(n^3)$;但是我们发现其实比较相邻的两个单词就可以了,比如 $a < b < c$ 则比较 $a < b$ 和 $b < c$, $a$ 和 $c$ 的关系便确定了。因此算法可以优化成比较相邻两个单词,时间复杂度为 $O(n²)$。
63
65
64
66
出现矛盾的情况:
65
67
66
- - ` g[i][j] = g[j][i] = true ` ;
68
+ - $ g[ i] [ j ] $ = $ g[ j] [ i ] $ = $ true$ ;
67
69
- 后一个单词是前一个单词的前缀;
68
- - 在拓扑排序后 ans 的长度小于统计到的字母个数。
70
+ - 在拓扑排序后 $ ans$ 的长度小于统计到的字母个数。
69
71
70
72
拓扑排序:
71
73
72
74
- 统计所有出现的字母入度;
73
- - 将所有入度为 0 的字母加入队列;
74
- - 当队列不空,出队并更新其他字母的入度,入度为 0 则入队,同时出队时将当前字母加入 ans 的结尾;
75
+ - 将所有入度为 $0$ 的字母加入队列;
76
+ - 当队列不空,出队并更新其他字母的入度,入度为 $0$ 则入队,同时出队时将当前字母加入 $ ans$ 的结尾;
75
77
- 得到的便是字母的拓扑序,也就是火星字典的字母顺序。
76
78
77
79
<!-- tabs:start -->
You can’t perform that action at this time.
0 commit comments