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]
- 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++ 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; }
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
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)
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); } }
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);
Yes 3 1 2 No
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles: