Open In App

Build original array from the given sub-sequences

Last Updated : 04 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer N and valid subsequences of an array of integers where every element is distinct and from the range [0, N – 1], the task is to find the original array.

Examples:  

Input: N = 6, v[] = { 
{1, 2, 3}, 
{1, 2}, 
{3, 4}, 
{5, 2}, 
{0, 5, 4}} 
Output: 0 1 5 2 3 4

Input: N = 10, v[] = { 
{9, 1, 2, 8, 3}, 
{6, 1, 2}, 
{9, 6, 3, 4}, 
{5, 2, 7}, 
{0, 9, 5, 4}} 
Output: 0 9 6 5 1 2 8 7 3 4 

Approach: Build a graph from given subsequences. Select each sub-sequence one by one and add an edge between two adjacent elements in the sub-sequence. After building the graph, perform topological sorting on the graph. 
Refer topological sorting for understanding topological sort. This topological ordering is the required array.

Algorithm

  1. Initialize an empty directed graph G(V, E), where V is the set of unique elements in the sub-sequences and E is the set of directed edges between consecutive elements in the sub-sequences.
  2. Calculate the indegree of each vertex in G.
  3. Initialize an empty queue Q.
  4. Enqueue all the vertices with indegree 0 into Q.
  5. Initialize an empty list L.
  6. While Q is not empty, do the following:
  7. Dequeue a vertex u from Q.
  8. Append u to L.
  9. For each vertex v adjacent to u, decrement its indegree by 1.
  10. If the indegree of v becomes 0, enqueue v into Q.
  11. If the size of L is less than V, then the sub-sequences contain a cycle, and it is not possible to generate the required array. Return an empty array.
  12. Otherwise, return the list L as the resultant array. 

Below is the implementation of the above approach:  

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to add edge to graph
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
}
 
// Function to calculate indegrees of all the vertices
void getindeg(vector<int> adj[], int V, vector<int>& indeg)
{
    // If there is an edge from i to x
    // then increment indegree of x
    for (int i = 0; i < V; i++) {
        for (auto x : adj[i]) {
            indeg[x]++;
        }
    }
}
 
// Function to perform topological sort
vector<int> topo(vector<int> adj[], int V, vector<int>& indeg)
{
    queue<int> q;
 
    // Push every node to the queue
    // which has no incoming edge
    for (int i = 0; i < V; i++) {
        if (indeg[i] == 0)
            q.push(i);
    }
    vector<int> res;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        res.push_back(u);
 
        // Since edge u is removed, update the indegrees
        // of all the nodes which had an incoming edge from u
        for (auto x : adj[u]) {
            indeg[x]--;
            if (indeg[x] == 0)
                q.push(x);
        }
    }
    return res;
}
 
// Function to generate the array
// from the given sub-sequences
vector<int> makearray(vector<vector<int> > v, int V)
{
 
    // Create the graph from the input sub-sequences
    vector<int> adj[V];
    for (int i = 0; i < v.size(); i++) {
        for (int j = 0; j < v[i].size() - 1; j++) {
 
            // Add edge between every two consecutive
            // elements of the given sub-sequences
            addEdge(adj, v[i][j], v[i][j + 1]);
        }
    }
 
    // Get the indegrees for all the vertices
    vector<int> indeg(V, 0);
    getindeg(adj, V, indeg);
 
    // Get the topological order of the created graph
    vector<int> res = topo(adj, V, indeg);
    return res;
}
 
// Driver code
int main()
{
    // Size of the required array
    int n = 10;
 
    // Given sub-sequences of the array
    vector<vector<int> > subseqs{ { 9, 1, 2, 8, 3 },
                                  { 6, 1, 2 },
                                  { 9, 6, 3, 4 },
                                  { 5, 2, 7 },
                                  { 0, 9, 5, 4 } };
 
    // Get the resultant array as vector
    vector<int> res = makearray(subseqs, n);
 
    // Printing the array
    for (auto x : res) {
        cout << x << " ";
    }
 
    return 0;
}


Java




// Java implementation of the approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// Function to add edge to graph
static void addEdge(ArrayList<ArrayList<Integer>> adj,
                    int u, int v)
{
    adj.get(u).add(v);
}
 
// Function to calculate indegrees of all the vertices
static void getindeg(ArrayList<ArrayList<Integer>> adj,
                        int V, ArrayList<Integer> indeg)
{
     
    // If there is an edge from i to x
    // then increment indegree of x
    for(int i = 0; i < V; i++)
    {
        for(int x: adj.get(i))
        {
            indeg.set(x, indeg.get(x) + 1);
        }
    }
}
 
// Function to perform topological sort
static ArrayList<Integer> topo(ArrayList<ArrayList<Integer>> adj,
                                  int V, ArrayList<Integer> indeg)
{
    Queue<Integer> q = new LinkedList<>();
     
    // Push every node to the queue
    // which has no incoming edge
    for(int i = 0; i < V; i++)
    {
        if (indeg.get(i) == 0)
        {
            q.add(i);
        }
    }
    ArrayList<Integer> res = new ArrayList<Integer>();
     
    while (q.size() > 0)
    {
        int u = q.poll();
        res.add(u);
         
        // Since edge u is removed, update the
        // indegrees of all the nodes which had
        // an incoming edge from u
        for(int x: adj.get(u))
        {
            indeg.set(x, indeg.get(x) - 1);
             
            if (indeg.get(x) == 0)
            {
                q.add(x);
            }
        }
    }
    return res;
}
 
// Function to generate the array
// from the given sub-sequences
static ArrayList<Integer> makearray(
    ArrayList<ArrayList<Integer>> v, int V)
{
     
    // Create the graph from the
    // input sub-sequences
    ArrayList<
    ArrayList<Integer>> adj = new ArrayList<
                                  ArrayList<Integer>>();
    for(int i = 0; i < V; i++)
    {
        adj.add(new ArrayList<Integer>());
    }
    for(int i = 0; i < v.size(); i++)
    {
        for(int j = 0; j < v.get(i).size() - 1; j++)
        {
             
            // Add edge between every two consecutive
            // elements of the given sub-sequences
            addEdge(adj, v.get(i).get(j),
                         v.get(i).get(j + 1));
        }
    }
     
    // Get the indegrees for all the vertices
    ArrayList<Integer> indeg = new ArrayList<Integer>();
    for(int i = 0; i < V; i++)
    {
        indeg.add(0);
    }
    getindeg(adj, V, indeg);
     
    // Get the topological order of the created graph
    ArrayList<Integer> res = topo(adj, V, indeg);
    return res;
}
 
// Driver code
public static void main(String[] args)
{
     
    // Size of the required array
    int n = 10;
     
    // Given sub-sequences of the array
    ArrayList<
    ArrayList<Integer>> subseqs = new ArrayList<
                                      ArrayList<Integer>>();
    subseqs.add(new ArrayList<Integer>(
        Arrays.asList(9, 1, 2, 8, 3)));
    subseqs.add(new ArrayList<Integer>(
        Arrays.asList(6, 1, 2)));
    subseqs.add(new ArrayList<Integer>(
        Arrays.asList(9, 6, 3, 4)));
    subseqs.add(new ArrayList<Integer>(
        Arrays.asList(5, 2, 7)));
    subseqs.add(new ArrayList<Integer>(
        Arrays.asList(0, 9, 5, 4)));
         
    // Get the resultant array as vector
    ArrayList<Integer> res = makearray(subseqs, n);
     
    // Printing the array
    for(int x: res)
    {
        System.out.print(x + " ");
    }
}
}
 
// This code is contributed by avanitrachhadiya2155


Python3




# Python3 implementation of the approach
from collections import deque
adj=[[] for i in range(100)]
 
# Function to add edge to graph
def addEdge(u, v):
    adj[u].append(v)
 
# Function to calculate indegrees of all the vertices
def getindeg(V,indeg):
 
    # If there is an edge from i to x
    # then increment indegree of x
    for i in range(V):
        for x in adj[i]:
            indeg[x] += 1
 
 
# Function to perform topological sort
def topo(V,indeg):
    q = deque()
 
    # Push every node to the queue
    # which has no incoming edge
    for i in range(V):
        if (indeg[i] == 0):
            q.appendleft(i)
    res=[]
    while (len(q) > 0):
        u = q.popleft()
        res.append(u)
 
        # Since edge u is removed, update the indegrees
        # of all the nodes which had an incoming edge from u
        for x in adj[u]:
            indeg[x]-=1
            if (indeg[x] == 0):
                q.appendleft(x)
 
    return res
 
 
# Function to generate the array
# from the given sub-sequences
def makearray(v, V):
 
    # Create the graph from the input sub-sequences
    for i in range(len(v)):
        for j in range(len(v[i])-1):
 
            # Add edge between every two consecutive
            # elements of the given sub-sequences
            addEdge(v[i][j], v[i][j + 1])
 
 
    # Get the indegrees for all the vertices
    indeg=[0 for i in range(V)]
    getindeg(V, indeg)
 
    # Get the topological order of the created graph
    res = topo(V, indeg)
    return res
 
# Driver code
 
# Size of the required array
n = 10
 
# Given sub-sequences of the array
subseqs=[ [ 9, 1, 2, 8, 3 ],
        [ 6, 1, 2 ],
        [ 9, 6, 3, 4 ],
        [ 5, 2, 7 ],
        [ 0, 9, 5, 4 ] ]
 
# Get the resultant array as vector
res = makearray(subseqs, n)
 
# Printing the array
for x in res:
    print(x,end=" ")
     
# This code is contributed by mohit kumar 29


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to add edge to graph
static void addEdge(List<List<int>> adj, int u, int v)
{
    adj[u].Add(v);
}
 
// Function to calculate indegrees of
// all the vertices
static void getindeg(List<List<int>> adj, int V,
                          List<int> indeg)
{
     
    // If there is an edge from i to x
    // then increment indegree of x
    for(int i = 0; i < V; i++)
    {
        foreach(int x in adj[i])
        {
            indeg[x]++;
        }
    }
}
 
// Function to perform topological sort
static List<int> topo(List<List<int>> adj, int V,
                           List<int> indeg)
{
    Queue<int> q = new Queue<int>();
     
    // Push every node to the queue
    // which has no incoming edge
    for(int i = 0; i < V; i++)
    {
        if (indeg[i] == 0)
        {
            q.Enqueue(i);
        }
    }
    List<int> res = new List<int>();
     
    while (q.Count > 0)
    {
        int u = q.Dequeue();
        res.Add(u);
         
        // Since edge u is removed, update the
        // indegrees of all the nodes which had
        // an incoming edge from u
        foreach(int x in adj[u])
        {
            indeg[x]--;
            if (indeg[x] == 0)
            {
                q.Enqueue(x);
            }
        }
    }
    return res;
}
 
// Function to generate the array
// from the given sub-sequences
static List<int> makearray(List<List<int>> v, int V)
{
     
    // Create the graph from the
    // input sub-sequences
    List<List<int>> adj = new List<List<int>>();
    for(int i = 0; i < V; i++)
    {
        adj.Add(new List<int>());
    }
    for(int i = 0; i < v.Count; i++)
    {
        for(int j = 0; j < v[i].Count - 1; j++)
        {
             
            // Add edge between every two consecutive
            // elements of the given sub-sequences
            addEdge(adj, v[i][j], v[i][j+1]);
        }
    }
     
    // Get the indegrees for all the vertices
    List<int> indeg = new List<int>();
    for(int i = 0; i < V; i++)
    {
        indeg.Add(0);
    }
    getindeg(adj, V, indeg);
     
    // Get the topological order
    // of the created graph
    List<int> res = topo(adj, V, indeg);
    return res;
}
 
// Driver code
static public void Main()
{
     
    // Size of the required array
    int n = 10;
     
    // Given sub-sequences of the array
    List<List<int>> subseqs = new List<List<int>>();
    subseqs.Add(new List<int>(){9, 1, 2, 8, 3});
    subseqs.Add(new List<int>(){6, 1, 2});
    subseqs.Add(new List<int>(){9, 6, 3, 4});
    subseqs.Add(new List<int>(){5, 2, 7});
    subseqs.Add(new List<int>(){0, 9, 5, 4});
     
    // Get the resultant array as vector
    List<int> res = makearray(subseqs, n);
     
    // Printing the array
    foreach(int x in res)
    {
        Console.Write(x + " ");
    }
}
}
 
// This code is contributed by rag2127


Javascript




<script>
// Javascript implementation of the approach
 
// Function to add edge to graph
function addEdge(adj, u, v)
{
    adj[u].push(v);
}
 
// Function to calculate indegrees of all the vertices
function getindeg(adj, V, indeg)
{
    // If there is an edge from i to x
    // then increment indegree of x
    for(let i = 0; i < V; i++)
    {
        for(let x = 0; x < adj[i].length; x++)
        {
            indeg[adj[i][x]] = indeg[adj[i][x]] + 1;
        }
    }
}
 
// Function to perform topological sort
function topo(adj, V, indeg)
{
    let q = [];
      
    // Push every node to the queue
    // which has no incoming edge
    for(let i = 0; i < V; i++)
    {
        if (indeg[i] == 0)
        {
            q.push(i);
        }
    }
    let res = [];
      
    while (q.length > 0)
    {
        let u = q.shift();
        res.push(u);
          
        // Since edge u is removed, update the
        // indegrees of all the nodes which had
        // an incoming edge from u
        for(let x = 0; x < adj[u].length; x++)
        {
            indeg[adj[u][x]] = indeg[adj[u][x]] - 1;
              
            if (indeg[adj[u][x]] == 0)
            {
                q.push(adj[u][x]);
            }
        }
    }
    return res;
}
 
// Function to generate the array
// from the given sub-sequences
function makearray(v,V)
{
    // Create the graph from the
    // input sub-sequences
    let adj = [];
    for(let i = 0; i < V; i++)
    {
        adj.push([]);
    }
    for(let i = 0; i < v.length; i++)
    {
        for(let j = 0; j < v[i].length - 1; j++)
        {
              
            // Add edge between every two consecutive
            // elements of the given sub-sequences
            addEdge(adj, v[i][j],
                         v[i][j+1]);
        }
    }
      
    // Get the indegrees for all the vertices
    let indeg = [];
    for(let i = 0; i < V; i++)
    {
        indeg.push(0);
    }
    getindeg(adj, V, indeg);
      
    // Get the topological order of the created graph
    let res = topo(adj, V, indeg);
    return res;
}
 
// Driver code
// Size of the required array
    let n = 10;
      
    // Given sub-sequences of the array
    let subseqs=[ [ 9, 1, 2, 8, 3 ],
        [ 6, 1, 2 ],
        [ 9, 6, 3, 4 ],
        [ 5, 2, 7 ],
        [ 0, 9, 5, 4 ] ];
          
    // Get the resultant array as vector
    let res = makearray(subseqs, n);
      
    // Printing the array
    for(let x = 0; x < res.length; x++)
    {
        document.write(res[x] + " ");
    }
 
// This code is contributed by patel2127
</script>


Output: 

0 9 6 5 1 2 8 7 3 4

 

Time complexity:  O(n*m), where n is the number of elements in the sequence and m is the maximum length of the sub-sequence. 
Auxiliary Space:  O(n*m), because for each element in the sequence, the maximum number of edges is m-1, giving a total of n*(m-1) edges in the graph. 

 


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads