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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find factorial of a number int factorial( int x)
{ int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
} // Function to find the MSB of a number int mostSigBit( int x)
{ int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
} // Function to calculate number of possible // permutations with minimum bitwise XOR int minXor( int N)
{ int highest_bit = mostSigBit(N - 1);
// The highest power of 2 before
// the largest number which will
// be part of the key pair with 0
int key = 1 << highest_bit;
// Count of elements in group 1
int grp1 = 0;
// Count of elements in group 2
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;
} // Driver code int main()
{ int N = 5;
// Function call
int ans = minXor(N);
cout << ans;
return 0;
} |
// Java program for the above approach import java.util.*;
public class GFG {
// Function to find factorial of a number
static int factorial( int x)
{
int ans = 1 ;
while (x > 0 ) {
ans = ans * x;
x--;
}
return ans;
}
// Function to find the MSB of a number
static int mostSigBit( int x)
{
int msb = - 1 ;
while (x != 0 ) {
x = x >> 1 ;
msb++;
}
return msb;
}
// Function to calculate number of possible
// permutations with minimum bitwise XOR
static int minXor( int N)
{
int highest_bit = mostSigBit(N - 1 );
// The highest power of 2 before the
// largest number which will be
// part of the key pair with 0
int key = 1 << highest_bit;
// Count of elements in group 1
int grp1 = 0 ;
// Count of elements in group 2
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;
}
// Driver code
public static void main(String[] args)
{
int N = 5 ;
// Function call
int ans = minXor(N);
System.out.println(ans);
}
} |
# Python code for the above approach # Function to find factorial of a number def factorial(x):
ans = 1 ;
while (x > 0 ):
ans = ans * x;
x - = 1
return ans;
# Function to find the MSB of a number def mostSigBit(x):
msb = - 1 ;
while (x ! = 0 ):
x = x >> 1 ;
msb + = 1
return msb;
# Function to calculate number of possible # permutations with minimum bitwise XOR def minXor(N):
highest_bit = mostSigBit(N - 1 );
# The highest power of 2 before
# the largest number which will
# be part of the key pair with 0
key = 1 << highest_bit;
# Count of elements in group 1
grp1 = 0 ;
# Count of elements in group 2
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;
# Driver code N = 5 ;
# Function call ans = minXor(N);
print (ans);
# This code is contributed by Saurabh jaiswal |
// C# program for the above approach using System;
class GFG {
// Function to find factorial of a number
static int factorial( int x)
{
int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
// Function to find the MSB of a number
static int mostSigBit( int x)
{
int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
// Function to calculate number of possible
// permutations with minimum bitwise XOR
static int minXor( int N)
{
int highest_bit = mostSigBit(N - 1);
// The highest power of 2 before the
// largest number which will be
// part of the key pair with 0
int key = 1 << highest_bit;
// Count of elements in group 1
int grp1 = 0;
// Count of elements in group 2
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;
}
// Driver code
public static void Main()
{
int N = 5;
// Function call
int ans = minXor(N);
Console.WriteLine(ans);
}
} // This code is contributed by Samim Hossain Mondal. |
<script> // JavaScript code for the above approach
// Function to find factorial of a number
function factorial(x) {
let ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
// Function to find the MSB of a number
function mostSigBit(x) {
let msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
// Function to calculate number of possible
// permutations with minimum bitwise XOR
function minXor(N) {
let highest_bit = mostSigBit(N - 1);
// The highest power of 2 before
// the largest number which will
// be part of the key pair with 0
let key = 1 << highest_bit;
// Count of elements in group 1
let grp1 = 0;
// Count of elements in group 2
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;
}
// Driver code
let N = 5;
// Function call
let ans = minXor(N);
document.write(ans);
// This code is contributed by Potta Lokesh
</script>
|
12
Time Complexity: O(N)
Auxiliary Space: O(1)