Valid Pairing of Numbers

Hard
0/120
Average time to solve is 50m
14 upvotes
Asked in companies
AppleSamsungRedBus

Problem statement

You are provided with a list of numbers from ‘0’ to (2 * ’N’ - 1). You have to find the minimum number of swaps needed to make every even number ‘E’ (present in the list) adjacent to (‘E’ + 1).

For Example:
List = [3, 0, 2, 1]

We have to make ‘0’ adjacent to ‘1’ and ‘2’ to ‘3’. And, to achieve this we can swap ‘0’ with ‘2’.

New list = [3, 2, 0, 1].

Therefore, the answer (minimum number of swaps) is equal to 1.
Note:
There will be only distinct numbers present in the given list.
Detailed explanation ( Input/output format, Notes, Images )
Input Format:
The first line contains a single integer ‘T’ representing the number of test cases. 

The first line of each test case will contain a single integer ‘N’ such that the size of the list is 2 * ‘N’.

The second line of each test case will contain 2 * ‘N’ integers separated by a single space that represents the elements/numbers present in the list initially.
Output Format:
For each test case, print the minimum number of swaps possible to make every even number ‘E’ adjacent to (‘E’ + 1).

Output for every test case will be printed in a separate line.
Note:
You don’t need to print anything; It has already been taken care of. Just implement the given function.
Constraints:
1 <= T <= 10
1 <= N <= 100
0 <= ARR[ i ] < 2 * N

Time limit: 1 sec
Sample Input 1:
1
2
3 0 2 1
Sample Output 1:
1
Explanation of sample input 1:
For the first test case, an explanation is given in the description.
Sample Input 2:
2
1
1 0
3
1 0 2 3 5 4
Sample Output 2:
0
0
Explanation for sample input 2:
In the first test case, the required pairing of all the even numbers is already done.

In the second test case, the required pairing of all the even numbers is already done.
Hint

Can you think of a solution using union and find the concept of disjoint sets?

Approaches (2)
Disjoint Sets

Consider the pair ‘E’ and ‘E’ + 1(where ‘E’ is a particular even number in the given list) as the vertex in the graph. As the size of the given list/array is 2 * ‘N’ and so, the graph will contain ‘N’ vertices. Now, we have to connect the edges between the required vertices. There will be an edge between the two pairs of numbers (two vertices) in the given list if there present ‘E’ in a pair and ‘E’ + 1 in the other or vice-versa.

 

Now, we have to only find the number of disjoint sets of vertices (number of connected components) in the graph. The answer (minimum number of swaps) will be ‘N’ - the total number of connected components in the graph.

 

Reference: https://cp-algorithms.com/data_structures/disjoint_set_union.html

 

We are going to use an additional function named “FIND” that helps in finding the parent node of a child node. It takes the “PARENT” array and number/vertex ‘X’ as arguments and returns the parent of ‘X’.

 

int find(vector<int> &parent, int x)

 

Where “PARENT” is the array that holds all the parent nodes (or we can say root nodes of every connected component present in the graph) and ‘X’ is the vertex whose parent we are trying to find.

 

The steps are as follows:

 

  1. In the “FIND” function
    • If ‘X’ is equal to “PARENT[ X ]” then return ‘X’.
    • Otherwise, we will do the path compression technique (see reference for further details). Make again a recursive call to the “FIND” function with arguments “PARENT” and “PARENT[ X ]”, and set the result obtained in “PARENT[ X ]”.
    • Return “PARENT[ X ]”.
  2. In the given function
    • Make a vector named “PARENT” of size ‘N’ and set ‘i’ for every “i-th” position in this vector. We are doing this so as to make all vertices disconnected initially.
    • Create a HashMap named “MP” that helps in mapping down two numbers in a particular pair.
    • Now, Iterate through the given list/array “ARR”. (say, iterator = ‘i’)
      • Create a variable named “NUM” and store ARR[ i ] / 2.
      • Now, check whether it presents already in “MP”.
        • If, it is not present then do MP[ NUM ] = i / 2
        • Else, find the parent of MP[ NUM ] (vertex that includes “NUM”), store in “V1” and the parent of ‘i’ / 2 ( vertex that includes “ARR[ i ]”) in “V2” and then make parent of “V1” equals to “V2”.
        • All we are trying to do in the above step is making an edge between the required vertices (described in the approach section).
    • Create a variable “CON_COMP” to store the number of connected components. Initialize it with 0.
    • Iterate through “PARENT” and if find the parent of ‘i’ is equal to ‘i’ then increment “CON_COMP” by 1.
    • Return ‘N’ - “CON_COMP”.
Time Complexity

O(N * log(N)), where ‘N’ is half of the size of the given array/list.

 

Since we are iterating through the given list and also performing the “FIND” operation on the “PARENT” array and so the overall time complexity will be O(N * log(N)).

Space Complexity

O(N), where ‘N’ is half of the size of the given array/list.

 

Since we are using the extra space for storing parent/root nodes and so, the overall space complexity will be O(N).

Code Solution
(100% EXP penalty)
Valid Pairing of Numbers
Full screen
Console