LeetCode 444 sequence reconstruction

Tech In Pieces發表於2020-11-28

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 ≤ 10^4. 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.

the description of this problem is trash, let’s start with the example:
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.

so we need to check if the seqs can form the graph that is org, and that’s the only one it can form.
return true or false if we can do that.

so the idea we should have is: let’s think of the seqs as a graph and we get the topological sort of this map and we assemble that out, if there is only one way to do this topological sort and it is org array.

public boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs)

for problem is like this, it’s not like this is a very difficult question, but actaully the idea is pretty clear, but there are many corner cases that we should thinking straight. and it’s not really easy to have a very clear solution(like how you are gonna implement you thought)

following code: BFS: map and indegree and queue.

class Solution {
    public boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs) {
        HashMap<Integer, HashSet<Integer>> map = new HashMap<>();
        HashMap<Integer, Integer> indegree = new HashMap<>();
        
        for (List<Integer> seq: seqs) {
            if (seq.size() == 1) { //this is important because we might have corner cases like this
                if (!map.containsKey(seq.get(0))) {
                    map.put(seq.get(0), new HashSet<>());
                    indegree.put(seq.get(0), 0);
                }
            } else {
                for (int i = 0; i < seq.size() - 1; i++) {
                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); //don;t use the getOrDefault() because we will add it later
            }
            if (map.get(seq.get(i)).add(seq.get(i+1))) { //if we successfully added it
                indegree.put(seq.get(i+1), indegree.get(seq.get(i+1)) + 1);
            }
            }
            }
        }
        Queue<Integer> queue = new LinkedList<>();
        
        for(Map.Entry<Integer, Integer> entry: indegree.entrySet()) {
            if (entry.getValue() == 0) queue.offer(entry.getKey());
        }
        
        int index= 0; //pointer on org 
        while (!queue.isEmpty()) {
            int size = queue.size();
            
            if (size > 1) return false; //if there is more than one way to go for each level
            int curr = queue.poll();
            if (index == org.length || curr != org[index++]) { //if org is reached the end of the org but the loop is still not finished
                return false;
            }
            for (int next: map.get(curr)) { //for every neighbor
                indegree.put(next, indegree.get(next) - 1); //update the indegree map od indegree
                if (indegree.get(next) == 0) { //if one of them is 0
                    queue.offer(next); //then we offer this to our queue
                }
            }
            
        }
        return index == org.length && index == map.size(); //index==org.length is for avoid the 
    }
}

相關文章