Skip to content

Commit c42b175

Browse files
authoredMar 22, 2024
feat: add solutions to lc/lcof2 problems (doocs#2475)
* lc No.0444.Sequence Reconstruction * lcof2 No.115.重建序列
1 parent 174bc92 commit c42b175

File tree

13 files changed

+309
-176
lines changed

13 files changed

+309
-176
lines changed
 

‎lcof2/剑指 Offer II 115. 重建序列/README.md

+67-38
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@
7373

7474
### 方法一:拓扑排序
7575

76-
BFS 实现。
76+
我们可以先遍历每个子序列 `seq`,对于每个相邻的元素 $a$ 和 $b$,我们在 $a$ 和 $b$ 之间建立一条有向边 $a \to b$。同时统计每个节点的入度,最后将所有入度为 $0$ 的节点加入队列中。
77+
78+
当队列中的节点个数等于 $1$ 时,我们取出队首节点 $i$,将 $i$ 从图中删除,并将 $i$ 的所有相邻节点的入度减 $1$。如果减 $1$ 后相邻节点的入度为 $0$,则将这些节点加入队列中。重复上述操作,直到队列的长度不为 $1$。此时判断队列是否为空,如果不为空,说明有多个最短超序列,返回 `false`;如果为空,说明只有一个最短超序列,返回 `true`
79+
80+
时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点的个数和边的个数。
7781

7882
<!-- tabs:start -->
7983

@@ -82,36 +86,36 @@ class Solution:
8286
def sequenceReconstruction(
8387
self, nums: List[int], sequences: List[List[int]]
8488
) -> bool:
85-
g = defaultdict(list)
86-
indeg = [0] * len(nums)
89+
n = len(nums)
90+
g = [[] for _ in range(n)]
91+
indeg = [0] * n
8792
for seq in sequences:
8893
for a, b in pairwise(seq):
89-
g[a - 1].append(b - 1)
90-
indeg[b - 1] += 1
91-
q = deque([i for i, v in enumerate(indeg) if v == 0])
92-
while q:
93-
if len(q) > 1:
94-
return False
94+
a, b = a - 1, b - 1
95+
g[a].append(b)
96+
indeg[b] += 1
97+
q = deque(i for i, x in enumerate(indeg) if x == 0)
98+
while len(q) == 1:
9599
i = q.popleft()
96100
for j in g[i]:
97101
indeg[j] -= 1
98102
if indeg[j] == 0:
99103
q.append(j)
100-
return True
104+
return len(q) == 0
101105
```
102106

103107
```java
104108
class Solution {
105-
public boolean sequenceReconstruction(int[] nums, int[][] sequences) {
109+
public boolean sequenceReconstruction(int[] nums, List<List<Integer>> sequences) {
106110
int n = nums.length;
107111
int[] indeg = new int[n];
108112
List<Integer>[] g = new List[n];
109113
Arrays.setAll(g, k -> new ArrayList<>());
110-
for (int[] seq : sequences) {
111-
for (int i = 1; i < seq.length; ++i) {
112-
int a = seq[i - 1] - 1, b = seq[i] - 1;
114+
for (var seq : sequences) {
115+
for (int i = 1; i < seq.size(); ++i) {
116+
int a = seq.get(i - 1) - 1, b = seq.get(i) - 1;
113117
g[a].add(b);
114-
indeg[b]++;
118+
++indeg[b];
115119
}
116120
}
117121
Deque<Integer> q = new ArrayDeque<>();
@@ -120,18 +124,15 @@ class Solution {
120124
q.offer(i);
121125
}
122126
}
123-
while (!q.isEmpty()) {
124-
if (q.size() > 1) {
125-
return false;
126-
}
127+
while (q.size() == 1) {
127128
int i = q.poll();
128129
for (int j : g[i]) {
129130
if (--indeg[j] == 0) {
130131
q.offer(j);
131132
}
132133
}
133134
}
134-
return true;
135+
return q.isEmpty();
135136
}
136137
}
137138
```
@@ -141,8 +142,8 @@ class Solution {
141142
public:
142143
bool sequenceReconstruction(vector<int>& nums, vector<vector<int>>& sequences) {
143144
int n = nums.size();
144-
vector<vector<int>> g(n);
145145
vector<int> indeg(n);
146+
vector<int> g[n];
146147
for (auto& seq : sequences) {
147148
for (int i = 1; i < seq.size(); ++i) {
148149
int a = seq[i - 1] - 1, b = seq[i] - 1;
@@ -151,42 +152,45 @@ public:
151152
}
152153
}
153154
queue<int> q;
154-
for (int i = 0; i < n; ++i)
155-
if (indeg[i] == 0) q.push(i);
156-
while (!q.empty()) {
157-
if (q.size() > 1) return false;
155+
for (int i = 0; i < n; ++i) {
156+
if (indeg[i] == 0) {
157+
q.push(i);
158+
}
159+
}
160+
while (q.size() == 1) {
158161
int i = q.front();
159162
q.pop();
160-
for (int j : g[i])
161-
if (--indeg[j] == 0) q.push(j);
163+
for (int j : g[i]) {
164+
if (--indeg[j] == 0) {
165+
q.push(j);
166+
}
167+
}
162168
}
163-
return true;
169+
return q.empty();
164170
}
165171
};
166172
```
167173
168174
```go
169175
func sequenceReconstruction(nums []int, sequences [][]int) bool {
170176
n := len(nums)
171-
g := make([][]int, n)
172177
indeg := make([]int, n)
178+
g := make([][]int, n)
173179
for _, seq := range sequences {
174-
for i := 1; i < len(seq); i++ {
175-
a, b := seq[i-1]-1, seq[i]-1
180+
for i, b := range seq[1:] {
181+
a := seq[i] - 1
182+
b -= 1
176183
g[a] = append(g[a], b)
177184
indeg[b]++
178185
}
179186
}
180187
q := []int{}
181-
for i, v := range indeg {
182-
if v == 0 {
188+
for i, x := range indeg {
189+
if x == 0 {
183190
q = append(q, i)
184191
}
185192
}
186-
for len(q) > 0 {
187-
if len(q) > 1 {
188-
return false
189-
}
193+
for len(q) == 1 {
190194
i := q[0]
191195
q = q[1:]
192196
for _, j := range g[i] {
@@ -196,7 +200,32 @@ func sequenceReconstruction(nums []int, sequences [][]int) bool {
196200
}
197201
}
198202
}
199-
return true
203+
return len(q) == 0
204+
}
205+
```
206+
207+
```ts
208+
function sequenceReconstruction(nums: number[], sequences: number[][]): boolean {
209+
const n = nums.length;
210+
const g: number[][] = Array.from({ length: n }, () => []);
211+
const indeg: number[] = Array(n).fill(0);
212+
for (const seq of sequences) {
213+
for (let i = 1; i < seq.length; ++i) {
214+
const [a, b] = [seq[i - 1] - 1, seq[i] - 1];
215+
g[a].push(b);
216+
++indeg[b];
217+
}
218+
}
219+
const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1);
220+
while (q.length === 1) {
221+
const i = q.pop()!;
222+
for (const j of g[i]) {
223+
if (--indeg[j] === 0) {
224+
q.push(j);
225+
}
226+
}
227+
}
228+
return q.length === 0;
200229
}
201230
```
202231

‎lcof2/剑指 Offer II 115. 重建序列/Solution.cpp

+13-8
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ class Solution {
22
public:
33
bool sequenceReconstruction(vector<int>& nums, vector<vector<int>>& sequences) {
44
int n = nums.size();
5-
vector<vector<int>> g(n);
65
vector<int> indeg(n);
6+
vector<int> g[n];
77
for (auto& seq : sequences) {
88
for (int i = 1; i < seq.size(); ++i) {
99
int a = seq[i - 1] - 1, b = seq[i] - 1;
@@ -12,15 +12,20 @@ class Solution {
1212
}
1313
}
1414
queue<int> q;
15-
for (int i = 0; i < n; ++i)
16-
if (indeg[i] == 0) q.push(i);
17-
while (!q.empty()) {
18-
if (q.size() > 1) return false;
15+
for (int i = 0; i < n; ++i) {
16+
if (indeg[i] == 0) {
17+
q.push(i);
18+
}
19+
}
20+
while (q.size() == 1) {
1921
int i = q.front();
2022
q.pop();
21-
for (int j : g[i])
22-
if (--indeg[j] == 0) q.push(j);
23+
for (int j : g[i]) {
24+
if (--indeg[j] == 0) {
25+
q.push(j);
26+
}
27+
}
2328
}
24-
return true;
29+
return q.empty();
2530
}
2631
};
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
func sequenceReconstruction(nums []int, sequences [][]int) bool {
22
n := len(nums)
3-
g := make([][]int, n)
43
indeg := make([]int, n)
4+
g := make([][]int, n)
55
for _, seq := range sequences {
6-
for i := 1; i < len(seq); i++ {
7-
a, b := seq[i-1]-1, seq[i]-1
6+
for i, b := range seq[1:] {
7+
a := seq[i] - 1
8+
b -= 1
89
g[a] = append(g[a], b)
910
indeg[b]++
1011
}
1112
}
1213
q := []int{}
13-
for i, v := range indeg {
14-
if v == 0 {
14+
for i, x := range indeg {
15+
if x == 0 {
1516
q = append(q, i)
1617
}
1718
}
18-
for len(q) > 0 {
19-
if len(q) > 1 {
20-
return false
21-
}
19+
for len(q) == 1 {
2220
i := q[0]
2321
q = q[1:]
2422
for _, j := range g[i] {
@@ -28,5 +26,5 @@ func sequenceReconstruction(nums []int, sequences [][]int) bool {
2826
}
2927
}
3028
}
31-
return true
29+
return len(q) == 0
3230
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
class Solution {
2-
public boolean sequenceReconstruction(int[] nums, int[][] sequences) {
2+
public boolean sequenceReconstruction(int[] nums, List<List<Integer>> sequences) {
33
int n = nums.length;
44
int[] indeg = new int[n];
55
List<Integer>[] g = new List[n];
66
Arrays.setAll(g, k -> new ArrayList<>());
7-
for (int[] seq : sequences) {
8-
for (int i = 1; i < seq.length; ++i) {
9-
int a = seq[i - 1] - 1, b = seq[i] - 1;
7+
for (var seq : sequences) {
8+
for (int i = 1; i < seq.size(); ++i) {
9+
int a = seq.get(i - 1) - 1, b = seq.get(i) - 1;
1010
g[a].add(b);
11-
indeg[b]++;
11+
++indeg[b];
1212
}
1313
}
1414
Deque<Integer> q = new ArrayDeque<>();
@@ -17,17 +17,14 @@ public boolean sequenceReconstruction(int[] nums, int[][] sequences) {
1717
q.offer(i);
1818
}
1919
}
20-
while (!q.isEmpty()) {
21-
if (q.size() > 1) {
22-
return false;
23-
}
20+
while (q.size() == 1) {
2421
int i = q.poll();
2522
for (int j : g[i]) {
2623
if (--indeg[j] == 0) {
2724
q.offer(j);
2825
}
2926
}
3027
}
31-
return true;
28+
return q.isEmpty();
3229
}
3330
}

‎lcof2/剑指 Offer II 115. 重建序列/Solution.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ class Solution:
22
def sequenceReconstruction(
33
self, nums: List[int], sequences: List[List[int]]
44
) -> bool:
5-
g = defaultdict(list)
6-
indeg = [0] * len(nums)
5+
n = len(nums)
6+
g = [[] for _ in range(n)]
7+
indeg = [0] * n
78
for seq in sequences:
89
for a, b in pairwise(seq):
9-
g[a - 1].append(b - 1)
10-
indeg[b - 1] += 1
11-
q = deque([i for i, v in enumerate(indeg) if v == 0])
12-
while q:
13-
if len(q) > 1:
14-
return False
10+
a, b = a - 1, b - 1
11+
g[a].append(b)
12+
indeg[b] += 1
13+
q = deque(i for i, x in enumerate(indeg) if x == 0)
14+
while len(q) == 1:
1515
i = q.popleft()
1616
for j in g[i]:
1717
indeg[j] -= 1
1818
if indeg[j] == 0:
1919
q.append(j)
20-
return True
20+
return len(q) == 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function sequenceReconstruction(nums: number[], sequences: number[][]): boolean {
2+
const n = nums.length;
3+
const g: number[][] = Array.from({ length: n }, () => []);
4+
const indeg: number[] = Array(n).fill(0);
5+
for (const seq of sequences) {
6+
for (let i = 1; i < seq.length; ++i) {
7+
const [a, b] = [seq[i - 1] - 1, seq[i] - 1];
8+
g[a].push(b);
9+
++indeg[b];
10+
}
11+
}
12+
const q: number[] = indeg.map((v, i) => (v === 0 ? i : -1)).filter(v => v !== -1);
13+
while (q.length === 1) {
14+
const i = q.pop()!;
15+
for (const j of g[i]) {
16+
if (--indeg[j] === 0) {
17+
q.push(j);
18+
}
19+
}
20+
}
21+
return q.length === 0;
22+
}

0 commit comments

Comments
 (0)