Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. The org sequence is a permutation of the integers from 1 to n, with 1 ≤ n ≤ 104. Reconstruction means building a shortest common supersequence of the sequences in seqs (i.e., a shortest sequence so that all sequences in seqs are subsequences of it). Determine whether there is only one sequence that can be reconstructed from seqs and it is the org sequence.
Input:
org: [1,2,3], seqs:[[1,2],[1,3]]Output:
falseExplanation:
[1,2,3]is not the only one sequence that can be reconstructed, because [1,3,2]is also a valid sequence that can be reconstructed.
Input:
org: [1,2,3], seqs:[[1,2],[1,3],[2,3]]Output:
trueExplanation:
The sequences [1,2],[1,3], and [2,3] can uniquely reconstruct the original sequence [1,2,3].
We can model the problem as a directed graph and use topological sort. If at any point there is more than one node with in-degree zero, the reconstruction is not unique. We also need to check that the reconstructed sequence matches the original.
classSolution {
public:bool sequenceReconstruction(vector<int>& org, vector<vector<int>>& seqs) {
unordered_map<int, unordered_set<int>> g;
unordered_map<int, int> indeg;
for (auto& seq : seqs) {
for (int i =0; i < seq.size(); ++i) {
if (!g.count(seq[i])) g[seq[i]] = {};
if (!indeg.count(seq[i])) indeg[seq[i]] =0;
if (i >0&& g[seq[i-1]].insert(seq[i]).second) indeg[seq[i]]++;
}
}
if (g.size() != org.size()) return false;
queue<int> q;
for (auto& [k, v] : indeg) if (v ==0) q.push(k);
vector<int> res;
while (!q.empty()) {
if (q.size() >1) return false;
int u = q.front(); q.pop();
res.push_back(u);
for (int v : g[u]) if (--indeg[v] ==0) q.push(v);
}
return res == org;
}
};
import java.util.*;
classSolution {
publicbooleansequenceReconstruction(int[] org, List<List<Integer>> seqs) {
Map<Integer, Set<Integer>> g =new HashMap<>();
Map<Integer, Integer> indeg =new HashMap<>();
for (List<Integer> seq : seqs) {
for (int i = 0; i < seq.size(); ++i) {
g.putIfAbsent(seq.get(i), new HashSet<>());
indeg.putIfAbsent(seq.get(i), 0);
if (i > 0 && g.get(seq.get(i-1)).add(seq.get(i))) indeg.put(seq.get(i), indeg.get(seq.get(i))+1);
}
}
if (g.size() != org.length) returnfalse;
Queue<Integer> q =new LinkedList<>();
for (int k : indeg.keySet()) if (indeg.get(k) == 0) q.offer(k);
List<Integer> res =new ArrayList<>();
while (!q.isEmpty()) {
if (q.size() > 1) returnfalse;
int u = q.poll();
res.add(u);
for (int v : g.get(u)) if (indeg.put(v, indeg.get(v)-1) == 1) q.offer(v);
}
if (res.size() != org.length) returnfalse;
for (int i = 0; i < org.length; ++i) if (res.get(i) != org[i]) returnfalse;
returntrue;
}
}
classSolution {
funsequenceReconstruction(org: IntArray, seqs: List<List<Int>>): Boolean {
val g = mutableMapOf<Int, MutableSet<Int>>()
val indeg = mutableMapOf<Int, Int>()
for (seq in seqs) {
for (i in seq.indices) {
g.getOrPut(seq[i]) { mutableSetOf() }
indeg.putIfAbsent(seq[i], 0)
if (i > 0&& g[seq[i-1]]!!.add(seq[i])) indeg[seq[i]] = indeg[seq[i]]!! + 1 }
}
if (g.size != org.size) returnfalseval q = ArrayDeque<Int>()
for ((k, v) in indeg) if (v ==0) q.add(k)
val res = mutableListOf<Int>()
while (q.isNotEmpty()) {
if (q.size > 1) returnfalseval u = q.removeFirst()
res.add(u)
for (v in g[u]!!) {
indeg[v] = indeg[v]!! - 1if (indeg[v] ==0) q.add(v)
}
}
if (res.size != org.size) returnfalsefor (i in org.indices) if (res[i] != org[i]) returnfalsereturntrue }
}
classSolution:
defsequenceReconstruction(self, org: list[int], seqs: list[list[int]]) -> bool:
from collections import defaultdict, deque
g = defaultdict(set)
indeg = defaultdict(int)
for seq in seqs:
for i, v in enumerate(seq):
if v notin g: g[v] = set()
if v notin indeg: indeg[v] =0if i >0and seq[i] notin g[seq[i-1]]:
g[seq[i-1]].add(seq[i])
indeg[seq[i]] +=1if len(g) != len(org): returnFalse q = deque([k for k in indeg if indeg[k] ==0])
res = []
while q:
if len(q) >1: returnFalse u = q.popleft()
res.append(u)
for v in g[u]:
indeg[v] -=1if indeg[v] ==0: q.append(v)
return res == org