Count of permutations with minimum possible maximum XOR of adjacent pairs
Last Updated :
27 Apr, 2023
Given an integer N, consider an array having elements in the range [0, N-1] such that the maximum Bitwise XOR of all adjacent pairs is minimum out of all possible permutations of the array. Find the number of such permutations.
Examples:
Input: N = 3
Output: 2
Explanation:
A[] = {2, 0, 1}, Maximum of XOR(2, 0) and XOR(0, 1) is 2
A[] = {1, 0, 2}, Maximum of XOR(1, 0) and XOR(0, 2) is 2
All other permutations of the array have maximum XOR greater than
2, hence the above two are the only permutations with the minimum XOR.
Input: N = 5
Output: 12
Explanation: The permutations are:
{1, 2, 3, 0, 4}, {1, 3, 2, 0, 4}, {2, 1, 3, 0, 4}, {3, 2, 1, 0, 4}, {3, 1, 2, 0, 4}, {2, 3, 1, 0, 4},
{4, 0, 1, 2, 3}, {4, 0, 1, 3, 2}, {4, 0, 2, 3, 1}, {4, 0, 2, 1, 3}, {4, 0, 3, 1, 2}, {4, 0, 3, 2, 1}.
All these permutations have maximum value of XOR as 4 which is the minimum possible.
Approach: If all elements are written in their binary representations, they can be divided into two groups based on the condition that who has the maximum possible leftmost set-bit set. So one group will have elements with the maximum possible leftmost bit set and the other will contain the remaining elements. Following is the main observation to solve the problem:
- The key observation here is that the maximum XOR will occur when the adjacent pairs are from two different groups,
- So to minimize the maximum, the permutation has to be such that there is only one adjacent pair whose elements are from different groups and that key pair will consist of 0 and the highest integral power of 2 before N. As the power of 2 will have only 1-bit set as compared to all integers greater than it and 0, of course, has no bit-set they make the perfect optimal pair.
- Elements of the same group will remain on the same side of the key pair i.e. elements with most significant bits set stay on the side of highest integral power of 2 and the others on the opposite side.
- The final answer = number of permutations on the left of key pair * number of permutations on the right of key pair * 2.
Follow the steps mentioned below to implement the above observation:
- Find the maximum possible leftmost setbit.
- Now count the number of elements in each group.
- Find the key pair.
- Count the permutations on each side and multiply them with each other and 2.
- Return this multiplied value as the answer.
Below is the implementation for the above algorithm:
C++
#include <bits/stdc++.h>
using namespace std;
int factorial( int x)
{
int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
int mostSigBit( int x)
{
int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
int minXor( int N)
{
int highest_bit = mostSigBit(N - 1);
int key = 1 << highest_bit;
int grp1 = 0;
int grp2 = 0;
for ( int i = 1; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
int ans = (factorial(grp1)
* factorial(grp2))
* 2;
return ans;
}
int main()
{
int N = 5;
int ans = minXor(N);
cout << ans;
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int factorial( int x)
{
int ans = 1 ;
while (x > 0 ) {
ans = ans * x;
x--;
}
return ans;
}
static int mostSigBit( int x)
{
int msb = - 1 ;
while (x != 0 ) {
x = x >> 1 ;
msb++;
}
return msb;
}
static int minXor( int N)
{
int highest_bit = mostSigBit(N - 1 );
int key = 1 << highest_bit;
int grp1 = 0 ;
int grp2 = 0 ;
for ( int i = 1 ; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
int ans = (factorial(grp1)
* factorial(grp2))
* 2 ;
return ans;
}
public static void main(String[] args)
{
int N = 5 ;
int ans = minXor(N);
System.out.println(ans);
}
}
|
Python3
def factorial(x):
ans = 1 ;
while (x > 0 ):
ans = ans * x;
x - = 1
return ans;
def mostSigBit(x):
msb = - 1 ;
while (x ! = 0 ):
x = x >> 1 ;
msb + = 1
return msb;
def minXor(N):
highest_bit = mostSigBit(N - 1 );
key = 1 << highest_bit;
grp1 = 0 ;
grp2 = 0 ;
for i in range ( 1 , N) :
if (i > key):
grp2 + = 1
elif (i < key):
grp1 + = 1
ans = (factorial(grp1) * factorial(grp2)) * 2
return ans;
N = 5 ;
ans = minXor(N);
print (ans);
|
C#
using System;
class GFG {
static int factorial( int x)
{
int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
static int mostSigBit( int x)
{
int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
static int minXor( int N)
{
int highest_bit = mostSigBit(N - 1);
int key = 1 << highest_bit;
int grp1 = 0;
int grp2 = 0;
for ( int i = 1; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
int ans = (factorial(grp1)
* factorial(grp2))
* 2;
return ans;
}
public static void Main()
{
int N = 5;
int ans = minXor(N);
Console.WriteLine(ans);
}
}
|
Javascript
<script>
function factorial(x) {
let ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
function mostSigBit(x) {
let msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
function minXor(N) {
let highest_bit = mostSigBit(N - 1);
let key = 1 << highest_bit;
let grp1 = 0;
let grp2 = 0;
for (let i = 1; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
let ans = (factorial(grp1)
* factorial(grp2))
* 2;
return ans;
}
let N = 5;
let ans = minXor(N);
document.write(ans);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...