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++ 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 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 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# 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 |
<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> |
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.