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 4Input: 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
- 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.
- Calculate the indegree of each vertex in G.
- Initialize an empty queue Q.
- Enqueue all the vertices with indegree 0 into Q.
- Initialize an empty list L.
- While Q is not empty, do the following:
- Dequeue a vertex u from Q.
- Append u to L.
- For each vertex v adjacent to u, decrement its indegree by 1.
- If the indegree of v becomes 0, enqueue v into Q.
- 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.
- 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 graphvoid addEdge(vector<int> adj[], int u, int v){ adj[u].push_back(v);}// Function to calculate indegrees of all the verticesvoid 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 sortvector<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-sequencesvector<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 codeint 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 graphstatic void addEdge(ArrayList<ArrayList<Integer>> adj, int u, int v){ adj.get(u).add(v);}// Function to calculate indegrees of all the verticesstatic 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 sortstatic 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 approachfrom collections import dequeadj=[[] for i in range(100)]# Function to add edge to graphdef addEdge(u, v): adj[u].append(v)# Function to calculate indegrees of all the verticesdef 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 sortdef 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-sequencesdef 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 arrayn = 10# Given sub-sequences of the arraysubseqs=[ [ 9, 1, 2, 8, 3 ], [ 6, 1, 2 ], [ 9, 6, 3, 4 ], [ 5, 2, 7 ], [ 0, 9, 5, 4 ] ]# Get the resultant array as vectorres = makearray(subseqs, n)# Printing the arrayfor 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 graphstatic void addEdge(List<List<int>> adj, int u, int v){ adj[u].Add(v);}// Function to calculate indegrees of// all the verticesstatic 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 sortstatic 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 graphfunction addEdge(adj, u, v){ adj[u].push(v);}// Function to calculate indegrees of all the verticesfunction 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 sortfunction 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-sequencesfunction 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> |
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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

… [Trackback]
[…] Info on that Topic: geeksforgeeks.org/build-original-array-from-the-given-sub-sequences/ […]
… [Trackback]
[…] Find More on on that Topic: geeksforgeeks.org/build-original-array-from-the-given-sub-sequences/ […]