Open In App

Check if permutation of size N can form uniquely

Improve
Improve
Like Article
Like
Save
Share
Report

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);
Output

Yes
3 1 2 
No

Time Complexity: O(N)  
Auxiliary Space: O(N)

Related Articles:



Last Updated : 28 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads