Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs.
aboved sentence may seems hard to understand, but take a look at the next two examples:
ex1:
Input: org = [1,2,3], seqs = [[1,2],[1,3]]
Output: false
Explanation: [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.
ex2:
Input: org = [1,2,3], seqs = [[1,2],[1,3],[2,3]]
Output: true
Explanation: The sequences [1,2], [1,3], and [2,3] can uniquely reconstruct the original sequence [1,2,3].
Just remeber, the inner order of seq array matters.
so the problem can be transferred as:
given a set of directed edges(which is array seq), and you need to check that if there is exactly only onw way from org[0] to org[org.length - 1], and that path is exactly that given org.
public class Solution {
public boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs) {
Map<Integer, Set<Integer>> map = new HashMap<>(); //stores node and its corresponding linked nodes
Map<Integer, Integer> indegree = new HashMap<>(); //stores the indegree of each node
for(List<Integer> seq: seqs) {
if(seq.size() == 1) { //if we only have one element in each seq
if(!map.containsKey(seq.get(0))) { //
map.put(seq.get(0), new HashSet<>());
indegree.put(seq.get(0), 0);
}
} else { //if we have more than one elements in each seq
for(int i = 0; i < seq.size() - 1; i++) { //add and calculate each one of them in seqs
if(!map.containsKey(seq.get(i))) {
map.put(seq.get(i), new HashSet<>());
indegree.put(seq.get(i), 0);
}
if(!map.containsKey(seq.get(i + 1))) {
map.put(seq.get(i + 1), new HashSet<>());
indegree.put(seq.get(i + 1), 0);
}
if(map.get(seq.get(i)).add(seq.get(i + 1))) {
indegree.put(seq.get(i + 1), indegree.get(seq.get(i + 1)) + 1);
}
}
}
}
if (map.size() != org.length) return false;
Queue<Integer> queue = new LinkedList<>(); //bfs
for(Map.Entry<Integer, Integer> entry: indegree.entrySet()) {
if(entry.getValue() == 0) queue.offer(entry.getKey()); //put every starting point as the first level, but shouldn't we use entry.getValue() == org[0]?
}
int index = 0;
while(!queue.isEmpty()) {
int size = queue.size();
if(size > 1) return false; //if size
int curr = queue.poll();
if(index == org.length || curr != org[index++]) return false;
for(int next: map.get(curr)) {
indegree.put(next, indegree.get(next) - 1); //update indegree of its neighbor to --
if(indegree.get(next) == 0) queue.offer(next); // only those with updated indegree is 0, will we add it into queue, WHY????
}
}
return index == org.length;
}
}
so in general, the main idea is to constrcut the graph and then use queue to bfs it, but there are two places I don’t quite understand, the first is why the first layer should be adding start nodes? and the second is when bfs, why we only add all indegree==0 as the next layer