Skip to content

Commit 9405562

Browse files
committed
feat: update solutions to lc/lcof2 problems: Sequence Reconstruction
* lc No.0444 & lcof2 No.115.Sequence Reconstruction
1 parent cc48369 commit 9405562

File tree

11 files changed

+348
-670
lines changed

11 files changed

+348
-670
lines changed

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

Lines changed: 101 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,79 @@
44

55
<!-- 这里写题目描述 -->
66

7-
<p>请判断原始的序列&nbsp;<code>org</code>&nbsp;是否可以从序列集&nbsp;<code>seqs</code>&nbsp;中唯一地 <strong>重建&nbsp;</strong>。</p>
7+
<p>给定一个长度为 <code>n</code> 的整数数组 <code>nums</code> ,其中 <code>nums</code> 是范围为 <code>[1,n]</code> 的整数的排列。还提供了一个 2D 整数数组&nbsp;<code>sequences</code>&nbsp;,其中&nbsp;<code>sequences[i]</code>&nbsp;&nbsp;<code>nums</code>&nbsp;的子序列。<br />
8+
检查 <code>nums</code> 是否是唯一的最短&nbsp;<strong>超序列</strong> 。最短 <strong>超序列</strong> 是 <strong>长度最短</strong> 的序列,并且所有序列&nbsp;<code>sequences[i]</code>&nbsp;都是它的子序列。对于给定的数组&nbsp;<code>sequences</code>&nbsp;,可能存在多个有效的 <strong>超序列</strong> 。</p>
89

9-
<p>序列&nbsp;<code>org</code>&nbsp;是 1 到 n 整数的排列,其中 1 &le; n &le; 10<sup>4</sup>。<strong>重建&nbsp;</strong>是指在序列集 <code>seqs</code> 中构建最短的公共超序列,即&nbsp;&nbsp;<code>seqs</code>&nbsp;中的任意序列都是该最短序列的子序列。</p>
10+
<ul>
11+
<li>例如,对于&nbsp;<code>sequences = [[1,2],[1,3]]</code>&nbsp;,有两个最短的 <strong>超序列</strong> ,<code>[1,2,3]</code> 和 <code>[1,3,2]</code> 。</li>
12+
<li>而对于&nbsp;<code>sequences = [[1,2],[1,3],[1,2,3]]</code>&nbsp;,唯一可能的最短 <strong>超序列</strong> 是 <code>[1,2,3]</code> 。<code>[1,2,3,4]</code> 是可能的超序列,但不是最短的。</li>
13+
</ul>
14+
15+
<p><em>如果 <code>nums</code> 是序列的唯一最短 <strong>超序列</strong> ,则返回 <code>true</code> ,否则返回 <code>false</code> 。</em><br />
16+
<strong>子序列</strong> 是一个可以通过从另一个序列中删除一些元素或不删除任何元素,而不改变其余元素的顺序的序列。</p>
1017

1118
<p>&nbsp;</p>
1219

1320
<p><strong>示例 1:</strong></p>
1421

1522
<pre>
16-
<strong>输入: </strong>org = [1,2,3], seqs = [[1,2],[1,3]]
17-
<strong>输出: </strong>false
18-
<strong>解释:</strong>[1,2,3] 不是可以被重建的唯一的序列,因为 [1,3,2] 也是一个合法的序列。
23+
<strong>输入:</strong>nums = [1,2,3], sequences = [[1,2],[1,3]]
24+
<strong>输出:</strong>false
25+
<strong>解释:</strong>有两种可能的超序列:[1,2,3]和[1,3,2]。
26+
序列 [1,2] 是[<u><strong>1,2</strong></u>,3]和[<u><strong>1</strong></u>,3,<u><strong>2</strong></u>]的子序列。
27+
序列 [1,3] 是[<u><strong>1</strong></u>,2,<u><strong>3</strong></u>]和[<u><strong>1,3</strong></u>,2]的子序列。
28+
因为 nums 不是唯一最短的超序列,所以返回false。
1929
</pre>
2030

2131
<p><strong>示例 2:</strong></p>
2232

2333
<pre>
24-
<strong>输入: </strong>org = [1,2,3], seqs = [[1,2]]
25-
<strong>输出: </strong>false
26-
<strong>解释:</strong>可以重建的序列只有 [1,2]。
34+
<strong>输入:</strong>nums = [1,2,3], sequences = [[1,2]]
35+
<strong>输出:</strong>false
36+
<strong>解释:</strong>最短可能的超序列为 [1,2]。
37+
序列 [1,2] 是它的子序列:[<u><strong>1,2</strong></u>]。
38+
因为 nums 不是最短的超序列,所以返回false。
2739
</pre>
2840

2941
<p><strong>示例 3:</strong></p>
3042

3143
<pre>
32-
<strong>输入: </strong>org = [1,2,3], seqs = [[1,2],[1,3],[2,3]]
33-
<strong>输出: </strong>true
34-
<strong>解释:</strong>序列 [1,2], [1,3] 和 [2,3] 可以被唯一地重建为原始的序列 [1,2,3]。
35-
</pre>
36-
37-
<p><strong>示例 4:</strong></p>
38-
39-
<pre>
40-
<strong>输入: </strong>org = [4,1,5,2,6,3], seqs = [[5,2,6,3],[4,1,5,2]]
41-
<strong>输出: </strong>true
42-
</pre>
44+
<strong>输入:</strong>nums = [1,2,3], sequences = [[1,2],[1,3],[2,3]]
45+
<strong>输出:</strong>true
46+
<strong>解释:</strong>最短可能的超序列为[1,2,3]。
47+
序列 [1,2] 是它的一个子序列:[<strong>1,2</strong>,3]。
48+
序列 [1,3] 是它的一个子序列:[<u><strong>1</strong></u>,2,<u><strong>3</strong></u>]。
49+
序列 [2,3] 是它的一个子序列:[1,<u><strong>2,3</strong></u>]。
50+
因为 nums 是唯一最短的超序列,所以返回true。</pre>
4351

4452
<p>&nbsp;</p>
4553

4654
<p><strong>提示:</strong></p>
4755

4856
<ul>
57+
<li><code>n == nums.length</code></li>
4958
<li><code>1 &lt;= n &lt;= 10<sup>4</sup></code></li>
50-
<li><code>org</code> 是数字 <code>1</code> 到 <code>n</code> 的一个排列</li>
51-
<li><code>1 &lt;= segs[i].length &lt;= 10<sup>5</sup></code></li>
52-
<li><code>seqs[i][j]</code> 是 <code>32</code> 位有符号整数</li>
59+
<li><code>nums</code>&nbsp;是&nbsp;<code>[1, n]</code>&nbsp;范围内所有整数的排列</li>
60+
<li><code>1 &lt;= sequences.length &lt;= 10<sup>4</sup></code></li>
61+
<li><code>1 &lt;= sequences[i].length &lt;= 10<sup>4</sup></code></li>
62+
<li><code>1 &lt;= sum(sequences[i].length) &lt;= 10<sup>5</sup></code></li>
63+
<li><code>1 &lt;= sequences[i][j] &lt;= n</code></li>
64+
<li><code>sequences</code>&nbsp;的所有数组都是 <strong>唯一 </strong>的</li>
65+
<li><code>sequences[i]</code>&nbsp;是&nbsp;<code>nums</code> 的一个子序列</li>
5366
</ul>
5467

5568
<p>&nbsp;</p>
5669

57-
<p>注意:本题与主站 444&nbsp;题相同:<a href="https://leetcode.cn/problems/sequence-reconstruction/">https://leetcode.cn/problems/sequence-reconstruction/</a></p>
70+
<p>注意:本题与主站 444&nbsp;题相同:<a href="https://leetcode.cn/problems/sequence-reconstruction/">https://leetcode-cn.com/problems/sequence-reconstruction/</a></p>
71+
5872

5973
## 解法
6074

6175
<!-- 这里可写通用的实现逻辑 -->
6276

63-
拓扑排序,BFS 实现。
77+
**方法一:拓扑排序**
78+
79+
BFS 实现。
6480

6581
<!-- tabs:start -->
6682

@@ -70,40 +86,23 @@
7086

7187
```python
7288
class Solution:
73-
def sequenceReconstruction(self, org: List[int], seqs: List[List[int]]) -> bool:
74-
n = len(org)
75-
nums = set()
76-
for seq in seqs:
77-
for num in seq:
78-
if num < 1 or num > n:
79-
return False
80-
nums.add(num)
81-
if len(nums) < n:
82-
return False
83-
84-
edges = defaultdict(list)
85-
indegree = [0] * (n + 1)
86-
for seq in seqs:
87-
i = seq[0]
88-
for j in seq[1:]:
89-
edges[i].append(j)
90-
indegree[j] += 1
91-
i = j
92-
q = deque()
93-
for i in range(1, n + 1):
94-
if indegree[i] == 0:
95-
q.append(i)
96-
cnt = 0
89+
def sequenceReconstruction(self, nums: List[int], sequences: List[List[int]]) -> bool:
90+
g = defaultdict(list)
91+
indeg = [0] * len(nums)
92+
for seq in sequences:
93+
for a, b in pairwise(seq):
94+
g[a - 1].append(b - 1)
95+
indeg[b - 1] += 1
96+
q = deque([i for i, v in enumerate(indeg) if v == 0])
9797
while q:
98-
if len(q) > 1 or org[cnt] != q[0]:
98+
if len(q) > 1:
9999
return False
100100
i = q.popleft()
101-
cnt += 1
102-
for j in edges[i]:
103-
indegree[j] -= 1
104-
if indegree[j] == 0:
101+
for j in g[i]:
102+
indeg[j] -= 1
103+
if indeg[j] == 0:
105104
q.append(j)
106-
return cnt == n
105+
return True
107106
```
108107

109108
### **Java**
@@ -112,54 +111,38 @@ class Solution:
112111

113112
```java
114113
class Solution {
115-
public boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs) {
116-
int n = org.length;
117-
Set<Integer> nums = new HashSet<>();
118-
for (List<Integer> seq : seqs) {
119-
for (int num : seq) {
120-
if (num < 1 || num > n) {
121-
return false;
122-
}
123-
nums.add(num);
124-
}
125-
}
126-
if (nums.size() < n) {
127-
return false;
114+
public boolean sequenceReconstruction(int[] nums, int[][] sequences) {
115+
int n = nums.length;
116+
int[] indeg = new int[n];
117+
List<Integer>[] g = new List[n];
118+
for (int i = 0; i < n; ++i) {
119+
g[i] = new ArrayList<>();
128120
}
129-
List<Integer>[] edges = new List[n + 1];
130-
for (int i = 0; i < edges.length; ++i) {
131-
edges[i] = new ArrayList<>();
132-
}
133-
int[] indegree = new int[n + 1];
134-
for (List<Integer> seq : seqs) {
135-
int i = seq.get(0);
136-
for (int j = 1; j < seq.size(); ++j) {
137-
edges[i].add(seq.get(j));
138-
++indegree[seq.get(j)];
139-
i = seq.get(j);
121+
for (int[] seq : sequences) {
122+
for (int i = 1; i < seq.length; ++i) {
123+
int a = seq[i - 1] - 1, b = seq[i] - 1;
124+
g[a].add(b);
125+
indeg[b]++;
140126
}
141127
}
142-
Queue<Integer> q = new LinkedList<>();
143-
for (int i = 1; i <= n; ++i) {
144-
if (indegree[i] == 0) {
128+
Deque<Integer> q = new ArrayDeque<>();
129+
for (int i = 0; i < n; ++i) {
130+
if (indeg[i] == 0) {
145131
q.offer(i);
146132
}
147133
}
148-
int cnt = 0;
149134
while (!q.isEmpty()) {
150-
if (q.size() > 1 || q.peek() != org[cnt]) {
135+
if (q.size() > 1) {
151136
return false;
152137
}
153-
++cnt;
154138
int i = q.poll();
155-
for (int j : edges[i]) {
156-
--indegree[j];
157-
if (indegree[j] == 0) {
139+
for (int j : g[i]) {
140+
if (--indeg[j] == 0) {
158141
q.offer(j);
159142
}
160143
}
161144
}
162-
return cnt == n;
145+
return true;
163146
}
164147
}
165148
```
@@ -169,102 +152,67 @@ class Solution {
169152
```cpp
170153
class Solution {
171154
public:
172-
bool sequenceReconstruction(vector<int>& org, vector<vector<int>>& seqs) {
173-
int n = org.size();
174-
unordered_set<int> nums;
175-
for (auto& seq : seqs)
155+
bool sequenceReconstruction(vector<int>& nums, vector<vector<int>>& sequences) {
156+
int n = nums.size();
157+
vector<vector<int>> g(n);
158+
vector<int> indeg(n);
159+
for (auto& seq : sequences)
176160
{
177-
for (int num : seq)
161+
for (int i = 1; i < seq.size(); ++i)
178162
{
179-
if (num < 1 || num > n) return false;
180-
nums.insert(num);
181-
}
182-
}
183-
if (nums.size() < n) return false;
184-
vector<vector<int>> edges(n + 1);
185-
vector<int> indegree(n + 1);
186-
for (auto& seq : seqs)
187-
{
188-
int i = seq[0];
189-
for (int j = 1; j < seq.size(); ++j)
190-
{
191-
edges[i].push_back(seq[j]);
192-
++indegree[seq[j]];
193-
i = seq[j];
163+
int a = seq[i - 1] - 1, b = seq[i] - 1;
164+
g[a].push_back(b);
165+
++indeg[b];
194166
}
195167
}
196168
queue<int> q;
197-
for (int i = 1; i <= n; ++i)
198-
{
199-
if (indegree[i] == 0) q.push(i);
200-
}
201-
int cnt = 0;
169+
for (int i = 0; i < n; ++i) if (indeg[i] == 0) q.push(i);
202170
while (!q.empty())
203171
{
204-
if (q.size() > 1 || q.front() != org[cnt]) return false;
205-
++cnt;
172+
if (q.size() > 1) return false;
206173
int i = q.front();
207174
q.pop();
208-
for (int j : edges[i])
209-
{
210-
--indegree[j];
211-
if (indegree[j] == 0) q.push(j);
212-
}
175+
for (int j : g[i]) if (--indeg[j] == 0) q.push(j);
213176
}
214-
return cnt == n;
177+
return true;
215178
}
216179
};
217180
```
218181
219182
### **Go**
220183
221184
```go
222-
func sequenceReconstruction(org []int, seqs [][]int) bool {
223-
n := len(org)
224-
nums := make(map[int]bool)
225-
for _, seq := range seqs {
226-
for _, num := range seq {
227-
if num < 1 || num > n {
228-
return false
229-
}
230-
nums[num] = true
231-
}
232-
}
233-
if len(nums) < n {
234-
return false
235-
}
236-
edges := make([][]int, n+1)
237-
indegree := make([]int, n+1)
238-
for _, seq := range seqs {
239-
i := seq[0]
240-
for _, j := range seq[1:] {
241-
edges[i] = append(edges[i], j)
242-
indegree[j]++
243-
i = j
185+
func sequenceReconstruction(nums []int, sequences [][]int) bool {
186+
n := len(nums)
187+
g := make([][]int, n)
188+
indeg := make([]int, n)
189+
for _, seq := range sequences {
190+
for i := 1; i < len(seq); i++ {
191+
a, b := seq[i-1]-1, seq[i]-1
192+
g[a] = append(g[a], b)
193+
indeg[b]++
244194
}
245195
}
246-
var q []int
247-
for i := 1; i <= n; i++ {
248-
if indegree[i] == 0 {
196+
q := []int{}
197+
for i, v := range indeg {
198+
if v == 0 {
249199
q = append(q, i)
250200
}
251201
}
252-
cnt := 0
253202
for len(q) > 0 {
254-
if len(q) > 1 || org[cnt] != q[0] {
203+
if len(q) > 1 {
255204
return false
256205
}
257206
i := q[0]
258207
q = q[1:]
259-
cnt++
260-
for _, j := range edges[i] {
261-
indegree[j]--
262-
if indegree[j] == 0 {
208+
for _, j := range g[i] {
209+
indeg[j]--
210+
if indeg[j] == 0 {
263211
q = append(q, j)
264212
}
265213
}
266214
}
267-
return cnt == n
215+
return true
268216
}
269217
```
270218

0 commit comments

Comments
 (0)