Check if permutation of size N can form uniquely
Given array A[][2] of size M, form a new array B[] of size N, for every i from 1 to M we know BA[i][0] < BA[i][1]. The task for this problem is to know if a permutation of size N can be uniquely formed. if it is possible to form print “Yes” along with the permutation otherwise print “No”. A permutation of size N is an array of size N in which each integer from 1 to N occurs exactly once.
Examples:
Input: N = 3, A[][2] = {{3, 1}, {2, 3}}
Output: Yes
3 1 2
Explanation: first element of required array B[] is greater than third element of B[] and third element of B[] is greater than second element of B[] which is B[1] > B[3] > B[2] therefore B[1] = 3, B [3] = 2 and B[2] = 1 (This can be visualized as nodes and edges of graph).
Input: N = 3, A[][2] = {{3, 1}, {3, 2}}
Output: No
Approach: The following approach can be used to solve the given problem
Breadth-First-Search can be used to solve this problem.
- This problem can be imagined as graph problem with nodes as array elements of required array B[] and edges as properties given in array A[][2]
Graph visualization for example 1
- This can be observed that required array B[] will be unique if topological order of Graph is unique.
- Topological order of graph is unique if next vertex to choose is always unique when traversing with Breadth-First-Search.
Follow the steps below to solve the problem:
- Declare adj[N + 1] for storing the adjacency list.
- Declare inDegree[N + 1] array to store indegree values of all nodes.
- Fill the adjacency list by iterating over all M edges.
- Declare Ans[N + 1] array where answers for permutation will be stored.
- Declare END variable with initial value N.
- Declare queue Q for BFS.
- If the queue has two or more elements print “No” and end the function.
- Take out the front element of the queue and store it in variable V.
- Set Ans[V] = END then decrement END variable by 1.
- Iterate to neighbors of V and reduce their in-degree by 1
- Check if their in-degree after reduction is zero, if it is zero then push that node in the queue.
- Finally, print “Yes” and print the array Ans[].
Below is the implementation of the above approach:
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to find if given permutation
// possible
void isPossible(int N, int A[][2], int M)
{
// Initializing adjaceny list
vector<vector<int> > adj(N + 1);
// Declaring array that stores degree
vector<int> inDegree(N + 1, 0);
// Filling adjacency list
for (int i = 0; i < M; i++) {
// Increasing indegree of
// A[i][0]th node
inDegree[A[i][0]]++;
// There is directed edge
// from A[i][1] to A[i][0]
adj[A[i][1]].push_back(A[i][0]);
}
// Declaring answer array where
// answers will be stored
int Ans[N + 1];
// Declaring BFS queue
queue<int> q;
// Filling the bfs queue with
// nodes with indegree zero
for (int i = 1; i <= N; i++)
if (inDegree[i] == 0)
q.push(i);
// Declaring variable to
// assign values
int end = N;
// Running while loop until
// queue becomes empty
while (!q.empty()) {
// If we have two nodes with
// indegree zero in our queue
// then permutation is
// not possible
if (q.size() > 1) {
// Permutation is
// not possible
cout << "No" << endl;
// End the function
return;
}
// Take out front element
// of queue
int v = q.front();
// Delete front element
// of queue
q.pop();
// Assigning value
Ans[v] = end--;
// Iterating for neigbours which
// has indegree zero
for (auto& u : adj[v]) {
// Reducing indegree by 1
inDegree[u]--;
// If inDegree is zero then
// push into queue
if (inDegree[u] == 0)
q.push(u);
}
}
// Permutation is possible
cout << "Yes" << endl;
// Printing the permutation
for (int i = 1; i <= N; i++)
cout << Ans[i] << " ";
// Ending in newline
cout << endl;
}
// Driver Code
int main()
{
// Input 1
int N = 3, A[][2] = { { 3, 1 }, { 2, 3 } };
int M = 2;
// Function Call
isPossible(N, A, M);
// Input 2
int N1 = 3, A1[][2] = { { 3, 1 }, { 3, 2 } };
int M1 = 2;
// Function Call
isPossible(N1, A1, M1);
return 0;
}
Java
import java.util.*;
public class Main {
// Function to find if given permutation possible
public static void isPossible(int N, int[][] A, int M)
{
// Initializing adjacency list
ArrayList<ArrayList<Integer> > adj
= new ArrayList<>();
for (int i = 0; i <= N; i++) {
adj.add(new ArrayList<>());
}
// Declaring array that stores degree
int[] inDegree = new int[N + 1];
// Filling adjacency list and inDegree array
for (int i = 0; i < M; i++) {
inDegree[A[i][0]]++;
adj.get(A[i][1]).add(A[i][0]);
}
// Declaring answer array where answers will be
// stored
int[] Ans = new int[N + 1];
// Declaring BFS queue
Queue<Integer> q = new LinkedList<>();
// Filling the bfs queue with nodes with indegree
// zero
for (int i = 1; i <= N; i++) {
if (inDegree[i] == 0) {
q.add(i);
}
}
// Declaring variable to assign values
int end = N;
// Running while loop until queue becomes empty
while (!q.isEmpty()) {
// If we have two nodes with indegree zero in
// our queue then permutation is not possible
if (q.size() > 1) {
// Permutation is not possible
System.out.println("No");
// End the function
return;
}
// Take out front element of queue
int v = q.poll();
// Assigning value
Ans[v] = end--;
// Iterating for neighbors which has indegree
// zero
for (int u : adj.get(v)) {
// Reducing indegree by 1
inDegree[u]--;
// If inDegree is zero then push into queue
if (inDegree[u] == 0) {
q.add(u);
}
}
}
// Permutation is possible
System.out.println("Yes");
// Printing the permutation
for (int i = 1; i <= N; i++) {
System.out.print(Ans[i] + " ");
}
System.out.println();
}
// Driver Code
public static void main(String[] args)
{
// Input 1
int N = 3;
int[][] A = { { 3, 1 }, { 2, 3 } };
int M = 2;
// Function Call
isPossible(N, A, M);
// Input 2
int N1 = 3;
int[][] A1 = { { 3, 1 }, { 3, 2 } };
int M1 = 2;
// Function Call
isPossible(N1, A1, M1);
}
}
// code is contributed by siddharth aher
Python3
from collections import defaultdict, deque
def is_possible(n, a, m):
# Initializing adjacency list
adj = defaultdict(list)
# Declaring array that stores degree
in_degree = [0] * (n+1)
# Filling adjacency list
for i in range(m):
# Increasing indegree of
# A[i][0]th node
in_degree[a[i][0]] += 1
# There is directed edge
# from A[i][1] to A[i][0]
adj[a[i][1]].append(a[i][0])
# Declaring answer array where
# answers will be stored
ans = [0] * (n+1)
# Filling the bfs queue with
# nodes with indegree zero
q = deque(i for i in range(1, n+1) if in_degree[i] == 0)
# Declaring variable to
# assign values
end = n
# Running while loop until
# queue becomes empty
while q:
# If we have two nodes with
# indegree zero in our queue
# then permutation is not possible
if len(q) > 1:
# Permutation is not possible
print("No")
return
# Take out front element
# of queue
v = q.popleft()
# Assigning value
ans[v] = end
end -= 1
# Iterating for neighbors which
# has indegree zero
for u in adj[v]:
# Reducing indegree by 1
in_degree[u] -= 1
# If inDegree is zero then
# push into queue
if in_degree[u] == 0:
q.append(u)
# Permutation is possible
print("Yes")
# Printing the permutation
print(*ans[1:])
# Driver Code
if __name__ == '__main__':
# Input 1
n, a, m = 3, [[3, 1], [2, 3]], 2
is_possible(n, a, m)
# Input 2
n, a, m = 3, [[3, 1], [3, 2]], 2
is_possible(n, a, m)
C#
using System;
using System.Collections.Generic;
public class MainClass
{
// Function to find if given permutation possible
public static void IsPossible(int N, int[,] A, int M)
{
// Initializing adjacency list
List<List<int>> adj = new List<List<int>>();
for (int i = 0; i <= N; i++)
{
adj.Add(new List<int>());
}
// Declaring array that stores degree
int[] inDegree = new int[N + 1];
// Filling adjacency list and inDegree array
for (int i = 0; i < M; i++)
{
inDegree[A[i, 0]]++;
adj[A[i, 1]].Add(A[i, 0]);
}
// Declaring answer array where answers will be
// stored
int[] Ans = new int[N + 1];
// Declaring BFS queue
Queue<int> q = new Queue<int>();
// Filling the bfs queue with nodes with indegree
// zero
for (int i = 1; i <= N; i++)
{
if (inDegree[i] == 0)
{
q.Enqueue(i);
}
}
// Declaring variable to assign values
int end = N;
// Running while loop until queue becomes empty
while (q.Count != 0)
{
// If we have two nodes with indegree zero in
// our queue then permutation is not possible
if (q.Count > 1)
{
// Permutation is not possible
Console.WriteLine("No");
// End the function
return;
}
// Take out front element of queue
int v = q.Dequeue();
// Assigning value
Ans[v] = end--;
// Iterating for neighbors which has indegree
// zero
foreach (int u in adj[v])
{
// Reducing indegree by 1
inDegree[u]--;
// If inDegree is zero then push into queue
if (inDegree[u] == 0)
{
q.Enqueue(u);
}
}
}
// Permutation is possible
Console.WriteLine("Yes");
// Printing the permutation
for (int i = 1; i <= N; i++)
{
Console.Write(Ans[i] + " ");
}
Console.WriteLine();
}
// Driver Code
public static void Main(string[] args)
{
// Input 1
int N = 3;
int[,] A = { { 3, 1 }, { 2, 3 } };
int M = 2;
// Function Call
IsPossible(N, A, M);
// Input 2
int N1 = 3;
int[,] A1 = { { 3, 1 }, { 3, 2 } };
int M1 = 2;
// Function Call
IsPossible(N1, A1, M1);
}
}
Javascript
function isPossible(N, A, M) {
// Initializing adjacency list
let adj = new Array(N + 1);
for (let i = 0; i <= N; i++) {
adj[i] = [];
}
// Declaring array that stores degree
let inDegree = new Array(N + 1).fill(0);
// Filling adjacency list and inDegree array
for (let i = 0; i < M; i++) {
inDegree[A[i][0]]++;
adj[A[i][1]].push(A[i][0]);
}
// Declaring answer array where answers will be stored
let Ans = new Array(N + 1).fill(0);
// Declaring BFS queue
let q = [];
// Filling the bfs queue with nodes with indegree zero
for (let i = 1; i <= N; i++) {
if (inDegree[i] == 0) {
q.push(i);
}
}
// Declaring variable to assign values
let end = N;
// Running while loop until queue becomes empty
while (q.length != 0) {
// If we have two nodes with indegree zero in our queue then permutation is not possible
if (q.length > 1) {
// Permutation is not possible
console.log("No");
// End the function
return;
}
// Take out front element of queue
let v = q.shift();
// Assigning value
Ans[v] = end--;
// Iterating for neighbors which has indegree zero
for (let u of adj[v]) {
// Reducing indegree by 1
inDegree[u]--;
// If inDegree is zero then push into queue
if (inDegree[u] == 0) {
q.push(u);
}
}
}
// Permutation is possible
console.log("Yes");
// Printing the permutation
let permutation = "";
for (let i = 1; i <= N; i++) {
permutation += Ans[i] + " ";
}
console.log(permutation);
}
// Driver Code
// Input 1
let N = 3;
let A = [
[3, 1],
[2, 3],
];
let M = 2;
// Function Call
isPossible(N, A, M);
// Input 2
let N1 = 3;
let A1 = [
[3, 1],
[3, 2],
];
let M1 = 2;
// Function Call
isPossible(N1, A1, M1);
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles:
Last Updated :
28 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...