Skip to content

Commit 2b0ac4d

Browse files
committed
feat: add solutions to lc/lcof2 problems
lc No.0269 & lcof2 No.114.Alien Dictionary
1 parent 7e52a6d commit 2b0ac4d

File tree

9 files changed

+995
-2
lines changed

9 files changed

+995
-2
lines changed

lcof2/剑指 Offer II 114. 外星文字典/README.md

Lines changed: 212 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,233 @@
5959

6060
<!-- 这里可写通用的实现逻辑 -->
6161

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²)`
65+
66+
出现矛盾的情况:
67+
68+
- `g[i][j] = g[j][i] = true`
69+
- 后一个单词是前一个单词的前缀;
70+
- 在拓扑排序后 ans 的长度小于统计到的字母个数。
71+
72+
拓扑排序:
73+
74+
- 统计所有出现的字母入度;
75+
- 将所有入度为 0 的字母加入队列;
76+
- 当队列不空,出队并更新其他字母的入度,入度为 0 则入队,同时出队时将当前字母加入 ans 的结尾;
77+
- 得到的便是字母的拓扑序,也就是火星字典的字母顺序。
78+
6279
<!-- tabs:start -->
6380

6481
### **Python3**
6582

6683
<!-- 这里可写当前语言的特殊实现逻辑 -->
6784

6885
```python
69-
86+
class Solution:
87+
def alienOrder(self, words: List[str]) -> str:
88+
g = [[False] * 26 for _ in range(26)]
89+
s = [False] * 26
90+
cnt = 0
91+
n = len(words)
92+
for i in range(n - 1):
93+
for c in words[i]:
94+
if cnt == 26:
95+
break
96+
o = ord(c) - ord('a')
97+
if not s[o]:
98+
cnt += 1
99+
s[o] = True
100+
m = len(words[i])
101+
for j in range(m):
102+
if j >= len(words[i + 1]):
103+
return ''
104+
c1, c2 = words[i][j], words[i + 1][j]
105+
if c1 == c2:
106+
continue
107+
o1, o2 = ord(c1) - ord('a'), ord(c2) - ord('a')
108+
if g[o2][o1]:
109+
return ''
110+
g[o1][o2] = True
111+
break
112+
for c in words[n - 1]:
113+
if cnt == 26:
114+
break
115+
o = ord(c) - ord('a')
116+
if not s[o]:
117+
cnt += 1
118+
s[o] = True
119+
120+
indegree = [0] * 26
121+
for i in range(26):
122+
for j in range(26):
123+
if i != j and s[i] and s[j] and g[i][j]:
124+
indegree[j] += 1
125+
q = deque()
126+
ans = []
127+
for i in range(26):
128+
if s[i] and indegree[i] == 0:
129+
q.append(i)
130+
while q:
131+
t = q.popleft()
132+
ans.append(chr(t + ord('a')))
133+
for i in range(26):
134+
if s[i] and i != t and g[t][i]:
135+
indegree[i] -= 1
136+
if indegree[i] == 0:
137+
q.append(i)
138+
return '' if len(ans) < cnt else ''.join(ans)
70139
```
71140

72141
### **Java**
73142

74143
<!-- 这里可写当前语言的特殊实现逻辑 -->
75144

76145
```java
146+
class Solution {
147+
148+
public String alienOrder(String[] words) {
149+
boolean[][] g = new boolean[26][26];
150+
boolean[] s = new boolean[26];
151+
int cnt = 0;
152+
int n = words.length;
153+
for (int i = 0; i < n - 1; ++i) {
154+
for (char c : words[i].toCharArray()) {
155+
if (cnt == 26) {
156+
break;
157+
}
158+
c -= 'a';
159+
if (!s[c]) {
160+
++cnt;
161+
s[c] = true;
162+
}
163+
}
164+
int m = words[i].length();
165+
for (int j = 0; j < m; ++j) {
166+
if (j >= words[i + 1].length()) {
167+
return "";
168+
}
169+
char c1 = words[i].charAt(j), c2 = words[i + 1].charAt(j);
170+
if (c1 == c2) {
171+
continue;
172+
}
173+
if (g[c2 - 'a'][c1 - 'a']) {
174+
return "";
175+
}
176+
g[c1 - 'a'][c2 - 'a'] = true;
177+
break;
178+
}
179+
}
180+
for (char c : words[n - 1].toCharArray()) {
181+
if (cnt == 26) {
182+
break;
183+
}
184+
c -= 'a';
185+
if (!s[c]) {
186+
++cnt;
187+
s[c] = true;
188+
}
189+
}
190+
191+
int[] indegree = new int[26];
192+
for (int i = 0; i < 26; ++i) {
193+
for (int j = 0; j < 26; ++j) {
194+
if (i != j && s[i] && s[j] && g[i][j]) {
195+
++indegree[j];
196+
}
197+
}
198+
}
199+
Deque<Integer> q = new LinkedList<>();
200+
for (int i = 0; i < 26; ++i) {
201+
if (s[i] && indegree[i] == 0) {
202+
q.offerLast(i);
203+
}
204+
}
205+
StringBuilder ans = new StringBuilder();
206+
while (!q.isEmpty()) {
207+
int t = q.pollFirst();
208+
ans.append((char) (t + 'a'));
209+
for (int i = 0; i < 26; ++i) {
210+
if (i != t && s[i] && g[t][i]) {
211+
if (--indegree[i] == 0) {
212+
q.offerLast(i);
213+
}
214+
}
215+
}
216+
}
217+
return ans.length() < cnt ? "" : ans.toString();
218+
}
219+
}
220+
221+
```
77222

223+
### **C++**
224+
225+
```cpp
226+
class Solution {
227+
public:
228+
string alienOrder(vector<string>& words) {
229+
vector<vector<bool>> g(26, vector<bool>(26));
230+
vector<bool> s(26);
231+
int cnt = 0;
232+
int n = words.size();
233+
for (int i = 0; i < n - 1; ++i)
234+
{
235+
for (char c : words[i])
236+
{
237+
if (cnt == 26) break;
238+
c -= 'a';
239+
if (!s[c])
240+
{
241+
++cnt;
242+
s[c] = true;
243+
}
244+
}
245+
int m = words[i].size();
246+
for (int j = 0; j < m; ++j)
247+
{
248+
if (j >= words[i + 1].size()) return "";
249+
char c1 = words[i][j], c2 = words[i + 1][j];
250+
if (c1 == c2) continue;
251+
if (g[c2 - 'a'][c1 - 'a']) return "";
252+
g[c1 - 'a'][c2 - 'a'] = true;
253+
break;
254+
}
255+
}
256+
for (char c : words[n - 1])
257+
{
258+
if (cnt == 26) break;
259+
c -= 'a';
260+
if (!s[c])
261+
{
262+
++cnt;
263+
s[c] = true;
264+
}
265+
}
266+
vector<int> indegree(26);
267+
for (int i = 0; i < 26; ++i)
268+
for (int j = 0; j < 26; ++j)
269+
if (i != j && s[i] && s[j] && g[i][j])
270+
++indegree[j];
271+
queue<int> q;
272+
for (int i = 0; i < 26; ++i)
273+
if (s[i] && indegree[i] == 0)
274+
q.push(i);
275+
string ans = "";
276+
while (!q.empty())
277+
{
278+
int t = q.front();
279+
ans += (t + 'a');
280+
q.pop();
281+
for (int i = 0; i < 26; ++i)
282+
if (i != t && s[i] && g[t][i])
283+
if (--indegree[i] == 0)
284+
q.push(i);
285+
}
286+
return ans.size() < cnt ? "" : ans;
287+
}
288+
};
78289
```
79290
80291
### **...**
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
class Solution {
2+
public:
3+
string alienOrder(vector<string>& words) {
4+
vector<vector<bool>> g(26, vector<bool>(26));
5+
vector<bool> s(26);
6+
int cnt = 0;
7+
int n = words.size();
8+
for (int i = 0; i < n - 1; ++i)
9+
{
10+
for (char c : words[i])
11+
{
12+
if (cnt == 26) break;
13+
c -= 'a';
14+
if (!s[c])
15+
{
16+
++cnt;
17+
s[c] = true;
18+
}
19+
}
20+
int m = words[i].size();
21+
for (int j = 0; j < m; ++j)
22+
{
23+
if (j >= words[i + 1].size()) return "";
24+
char c1 = words[i][j], c2 = words[i + 1][j];
25+
if (c1 == c2) continue;
26+
if (g[c2 - 'a'][c1 - 'a']) return "";
27+
g[c1 - 'a'][c2 - 'a'] = true;
28+
break;
29+
}
30+
}
31+
for (char c : words[n - 1])
32+
{
33+
if (cnt == 26) break;
34+
c -= 'a';
35+
if (!s[c])
36+
{
37+
++cnt;
38+
s[c] = true;
39+
}
40+
}
41+
vector<int> indegree(26);
42+
for (int i = 0; i < 26; ++i)
43+
for (int j = 0; j < 26; ++j)
44+
if (i != j && s[i] && s[j] && g[i][j])
45+
++indegree[j];
46+
queue<int> q;
47+
for (int i = 0; i < 26; ++i)
48+
if (s[i] && indegree[i] == 0)
49+
q.push(i);
50+
string ans = "";
51+
while (!q.empty())
52+
{
53+
int t = q.front();
54+
ans += (t + 'a');
55+
q.pop();
56+
for (int i = 0; i < 26; ++i)
57+
if (i != t && s[i] && g[t][i])
58+
if (--indegree[i] == 0)
59+
q.push(i);
60+
}
61+
return ans.size() < cnt ? "" : ans;
62+
}
63+
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
class Solution {
2+
public String alienOrder(String[] words) {
3+
boolean[][] g = new boolean[26][26];
4+
boolean[] s = new boolean[26];
5+
int cnt = 0;
6+
int n = words.length;
7+
for (int i = 0; i < n - 1; ++i) {
8+
for (char c : words[i].toCharArray()) {
9+
if (cnt == 26) {
10+
break;
11+
}
12+
c -= 'a';
13+
if (!s[c]) {
14+
++cnt;
15+
s[c] = true;
16+
}
17+
}
18+
int m = words[i].length();
19+
for (int j = 0; j < m; ++j) {
20+
if (j >= words[i + 1].length()) {
21+
return "";
22+
}
23+
char c1 = words[i].charAt(j), c2 = words[i + 1].charAt(j);
24+
if (c1 == c2) {
25+
continue;
26+
}
27+
if (g[c2 - 'a'][c1 - 'a']) {
28+
return "";
29+
}
30+
g[c1 - 'a'][c2 - 'a'] = true;
31+
break;
32+
}
33+
}
34+
for (char c : words[n - 1].toCharArray()) {
35+
if (cnt == 26) {
36+
break;
37+
}
38+
c -= 'a';
39+
if (!s[c]) {
40+
++cnt;
41+
s[c] = true;
42+
}
43+
}
44+
45+
int[] indegree = new int[26];
46+
for (int i = 0; i < 26; ++i) {
47+
for (int j = 0; j < 26; ++j) {
48+
if (i != j && s[i] && s[j] && g[i][j]) {
49+
++indegree[j];
50+
}
51+
}
52+
}
53+
Deque<Integer> q = new LinkedList<>();
54+
for (int i = 0; i < 26; ++i) {
55+
if (s[i] && indegree[i] == 0) {
56+
q.offerLast(i);
57+
}
58+
}
59+
StringBuilder ans = new StringBuilder();
60+
while (!q.isEmpty()) {
61+
int t = q.pollFirst();
62+
ans.append((char) (t + 'a'));
63+
for (int i = 0; i < 26; ++i) {
64+
if (i != t && s[i] && g[t][i]) {
65+
if (--indegree[i] == 0) {
66+
q.offerLast(i);
67+
}
68+
}
69+
}
70+
}
71+
return ans.length() < cnt ? "" : ans.toString();
72+
}
73+
}

0 commit comments

Comments
 (0)