Skip to content

Prepare For Coder Interview – Denny

  • Basic
  • Medium
  • Hard
  • Architect
  • Life

LeetCode: Sequence Reconstruction

Posted on February 19, 2018July 26, 2020 by braindenny

Sequence Reconstruction



Similar Problems:

  • CheatSheet: Leetcode For Code Interview
  • CheatSheet: Common Code Problems & Follow-ups
  • Tag: #topologicalsort, #bfs, #manydetails

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.

Example 1:

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.

Example 2:

Input:
org: [1,2,3], seqs: [[1,2]]

Output:
false

Explanation:
The reconstructed sequence can only be [1,2].

Example 3:

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].

Example 4:

Input:
org: [4,1,5,2,6,3], seqs: [[5,2,6,3],[4,1,5,2]]

Output:
true

Github: code.dennyzhang.com

Credits To: leetcode.com

Leave me comments, if you have better ways to solve.


  • Solution
// https://code.dennyzhang.com/sequence-reconstruction
// Basic Ideas: topological sort
//
//  Build the dependencies, and try to compose the graph
//  There should be no ambiguous.
//
//  Notice: watch out for invalid input
//      e.g, seqs: [[1,-9],[-9,-8],[-8,-9]]
//  Watch out duplicate edges
//      e.g, seqs: [[1,2],[1,2]]
//  Watch out: missing seqs:
//      e.g, org: [1], seqs: []
//
// Complexity: Time O(n+e), Space O(n+e)
func sequenceReconstruction(org []int, seqs [][]int) bool {
    indegrees := make([]int, len(org))
    for i, _ := range indegrees {
        indegrees[i] = -1
    }

    edges := map[int]map[int]bool{}
    for _, seq := range seqs {
        for _, n := range seq {
            n--
            if n<0 || n>=len(org) {
                return false
            }
            // initialize the node
            if indegrees[n] == -1 {
                indegrees[n] = 0
            }
            if _, ok := edges[n]; !ok {
                edges[n] = map[int]bool{}
            }
        }
        for i:=0; i+1<len(seq); i++ {
            n1, n2 := seq[i]-1, seq[i+1]-1
            // avoid duplicate edges
            if _, ok := edges[n1][n2]; !ok {
                // n1->n2
                indegrees[n2]++
                edges[n1][n2] = true
            }
        }
    }

    res := []int{}
    queue := []int{}
    for i, v := range indegrees {
        if v == 0 {
            queue = append(queue, i)
            res = append(res, i)
        }
    }

    if len(queue) > 1 {
        return false
    }

    for len(queue) > 0 {
        nexts := []int{}
        for _, node := range queue {
            for node2, _ := range edges[node] {
                indegrees[node2]--
                if indegrees[node2] == 0 {
                    nexts = append(nexts, node2)
                    res = append(res, node2)
                }
            }
        }
        queue = nexts
        if len(queue) > 1 {
            return false
        }
    }
    return len(res) == len(org)
}
// https://code.dennyzhang.com/sequence-reconstruction
// Basic Ideas: topological sort + bfs
//
//  Every time, there should be only one node with 0 incoming edges
//  There should be no circle. All nodes should be reachable
//
//  Notice: there would be duplicate edges
//  Notice: The default value of 0 for indegrees list might be misleading
//
// Complexity: Time O(n+e), Space O(n+e)
func sequenceReconstruction(org []int, seqs [][]int) bool {
    if len(org) == 0 {
        return len(seqs) == 0
    }
    indegrees := make([]int, len(org))
    for i, _ := range indegrees {
        indegrees[i] = -1
    }
    edges := map[int]map[int]bool{}
    // build edges
    for _, seq := range seqs {
        prev := -1
        for i:=0; i<len(seq); i++ {
            cur := seq[i]-1
            if cur >= len(org) || cur < 0 {
                return false
            }
            // mark the node as seen
            if indegrees[cur] == -1 {
                indegrees[cur] = 0
            }
            if prev != -1 {
                // mark the edge 
                if _, ok := edges[prev]; !ok {
                    edges[prev] = map[int]bool{}
                }
                if _, ok := edges[prev][cur]; !ok {
                    edges[prev][cur] = true
                    indegrees[cur]++
                }
            }
            prev = cur
        }
    }
    queue := []int{}
    for i, v := range indegrees {
        if v == 0 {
            queue = append(queue, i)
        }
    }
    index := 0
    for len(queue) == 1 {
        // examine the result when we pop
        node1 := queue[0]
        if org[index] != node1+1 {
            return false
        }
        index++
        indegrees[node1] = -1
        // get the nexts
        l := []int{}
        for node2, _ := range edges[node1] {
            indegrees[node2]--
            if indegrees[node2] == 0 {
                l = append(l, node2)            
            }
        }
        queue = l
    }
    return index == len(org)
}
linkedin
github
slack

Post Views: 3
Posted in MediumTagged #bfs, #manydetails, redo, topologicalsort

Post navigation

LeetCode: Palindrome Permutation II
LeetCode: Minimum Genetic Mutation

Leave a Reply Cancel reply

Your email address will not be published.

Tags

#array #backtracking #bfs #binarytree #bitmanipulation #blog #classic #codetemplate #combination #dfs #dynamicprogramming #game #graph #greedy #heap #inspiring #interval #linkedlist #manydetails #math #palindrome #recursive #slidingwindow #stack #string #subarray #trie #twopointer #twosum binarysearch editdistance hashmap intervaldp knapsack monotone oodesign presum rectangle redo review rotatelist series sql treetraversal unionfind

Recent Posts

  • a
  • a
  • a
  • a
  • a

Recent Comments

    Archives

    Categories

    • Amusing
    • Basic
    • Easy
    • Hard
    • Life
    • Medium
    • Resource
    • Review
    • Series
    • Uncategorized
    Proudly powered by WordPress | Theme: petals by Aurorum.