Given an array A consisting of N non-negative integers, the task is to choose an integer K such that the maximum of the xor values of K with all array elements is minimized. In other words find the minimum possible value of Z, where Z = max(A[i] xor K), 0 <= i <= n-1, for some value of K.
Examples:
Input: A = [1, 2, 3]
Output: 2
Explanation:
On choosing K = 3, max(A[i] xor 3) = 2, and this is the minimum possible value.
Input: A = [3, 2, 5, 6]
Output: 5
Approach: To solve the problem mentioned above we will use recursion. We will start from the most significant bit in the recursive function.
- In the recursive step, split the element into two sections – one having the current bit on and the other with current bit off. If any of the sections doesn’t have a single element, then this particular bit for K can be chosen such that the final xor value has 0 at this bit position (since our aim is to minimise this value) and then proceed to the next bit in the next recursive step.
- If both the sections have some elements, then explore both the possibilities by placing 0 and 1 at this bit position and calculating the answer using the corresponding section in next recursive call.
Let answer_on be the value if 1 is placed and answer_off be the value if 0 is placed at this position (pos). Since both sections are non empty whichever bit we choose for K, 2pos will be added to the final value.
For each recursive step:
answer = min(answer_on, answer_off) + 2pos
Below is the implementation of the above approach:
// C++ implementation to find Minimum // possible value of the maximum xor // in an array by choosing some integer #include <bits/stdc++.h> using namespace std;
// Function to calculate Minimum possible // value of the Maximum XOR in an array int calculate(vector< int >& section, int pos)
{ // base case
if (pos < 0)
return 0;
// Divide elements into two sections
vector< int > on_section, off_section;
// Traverse all elements of current
// section and divide in two groups
for ( auto el : section) {
if (((el >> pos) & 1) == 0)
off_section.push_back(el);
else
on_section.push_back(el);
}
// Check if one of the sections is empty
if (off_section.size() == 0)
return calculate(on_section, pos - 1);
if (on_section.size() == 0)
return calculate(off_section, pos - 1);
// explore both the possibilities using recursion
return min(calculate(off_section, pos - 1),
calculate(on_section, pos - 1))
+ (1 << pos);
} // Function to calculate minimum XOR value int minXorValue( int a[], int n)
{ vector< int > section;
for ( int i = 0; i < n; i++)
section.push_back(a[i]);
// Start recursion from the
// most significant pos position
return calculate(section, 30);
} // Driver code int main()
{ int N = 4;
int A[N] = { 3, 2, 5, 6 };
cout << minXorValue(A, N);
return 0;
} |
// Java implementation to find Minimum // possible value of the maximum xor // in an array by choosing some integer import java.util.*;
class GFG{
// Function to calculate Minimum possible // value of the Maximum XOR in an array static int calculate(Vector<Integer> section, int pos)
{ // Base case
if (pos < 0 )
return 0 ;
// Divide elements into two sections
Vector<Integer> on_section = new Vector<Integer>(),
off_section = new Vector<Integer>();
// Traverse all elements of current
// section and divide in two groups
for ( int el : section)
{
if (((el >> pos) & 1 ) == 0 )
off_section.add(el);
else
on_section.add(el);
}
// Check if one of the sections is empty
if (off_section.size() == 0 )
return calculate(on_section, pos - 1 );
if (on_section.size() == 0 )
return calculate(off_section, pos - 1 );
// Explore both the possibilities using recursion
return Math.min(calculate(off_section, pos - 1 ),
calculate(on_section, pos - 1 )) +
( 1 << pos);
} // Function to calculate minimum XOR value static int minXorValue( int a[], int n)
{ Vector<Integer> section = new Vector<Integer>();
for ( int i = 0 ; i < n; i++)
section.add(a[i]);
// Start recursion from the
// most significant pos position
return calculate(section, 30 );
} // Driver code public static void main(String[] args)
{ int N = 4 ;
int A[] = { 3 , 2 , 5 , 6 };
System.out.print(minXorValue(A, N));
} } // This code is contributed by Princi Singh |
# Python3 implementation to find Minimum # possible value of the maximum xor # in an array by choosing some integer # Function to calculate Minimum possible # value of the Maximum XOR in an array def calculate(section, pos):
# base case
if (pos < 0 ):
return 0
# Divide elements into two sections
on_section = []
off_section = []
# Traverse all elements of current
# section and divide in two groups
for el in section:
if (((el >> pos) & 1 ) = = 0 ):
off_section.append(el)
else :
on_section.append(el)
# Check if one of the sections is empty
if ( len (off_section) = = 0 ):
return calculate(on_section, pos - 1 )
if ( len (on_section) = = 0 ):
return calculate(off_section, pos - 1 )
# explore both the possibilities using recursion
return min (calculate(off_section, pos - 1 ),
calculate(on_section, pos - 1 )) + ( 1 << pos)
# Function to calculate minimum XOR value def minXorValue(a, n):
section = []
for i in range ( n):
section.append(a[i]);
# Start recursion from the
# most significant pos position
return calculate(section, 30 )
# Driver code if __name__ = = "__main__" :
N = 4
A = [ 3 , 2 , 5 , 6 ]
print (minXorValue(A, N))
# This code is contributed by chitranayal |
// C# implementation to find minimum // possible value of the maximum xor // in an array by choosing some integer using System;
using System.Collections.Generic;
class GFG{
// Function to calculate minimum possible // value of the maximum XOR in an array static int calculate(List< int > section, int pos)
{ // Base case
if (pos < 0)
return 0;
// Divide elements into two sections
List< int > on_section = new List< int >(),
off_section = new List< int >();
// Traverse all elements of current
// section and divide in two groups
foreach ( int el in section)
{
if (((el >> pos) & 1) == 0)
off_section.Add(el);
else
on_section.Add(el);
}
// Check if one of the sections is empty
if (off_section.Count == 0)
return calculate(on_section, pos - 1);
if (on_section.Count == 0)
return calculate(off_section, pos - 1);
// Explore both the possibilities using recursion
return Math.Min(calculate(off_section, pos - 1),
calculate(on_section, pos - 1)) +
(1 << pos);
} // Function to calculate minimum XOR value static int minXorValue( int []a, int n)
{ List< int > section = new List< int >();
for ( int i = 0; i < n; i++)
section.Add(a[i]);
// Start recursion from the
// most significant pos position
return calculate(section, 30);
} // Driver code public static void Main(String[] args)
{ int N = 4;
int []A = { 3, 2, 5, 6 };
Console.Write(minXorValue(A, N));
} } // This code is contributed by Princi Singh |
<script> // Javascript implementation to find Minimum // possible value of the maximum xor // in an array by choosing some integer // Function to calculate Minimum possible // value of the Maximum XOR in an array function calculate(section, pos)
{ // base case
if (pos < 0)
return 0;
// Divide elements into two sections
let on_section = [], off_section = [];
// Traverse all elements of current
// section and divide in two groups
for (let el = 0; el < section.length; el++) {
if (((section[el] >> pos) & 1) == 0)
off_section.push(section[el]);
else
on_section.push(section[el]);
}
// Check if one of the sections is empty
if (off_section.length == 0)
return calculate(on_section, pos - 1);
if (on_section.length == 0)
return calculate(off_section, pos - 1);
// explore both the possibilities using recursion
return Math.min(calculate(off_section, pos - 1),
calculate(on_section, pos - 1))
+ (1 << pos);
} // Function to calculate minimum XOR value function minXorValue(a, n)
{ let section = [];
for (let i = 0; i < n; i++)
section.push(a[i]);
// Start recursion from the
// most significant pos position
return calculate(section, 30);
} // Driver code let N = 4;
let A = [ 3, 2, 5, 6 ];
document.write(minXorValue(A, N));
</script> |
5
Time Complexity: O(N * log(max(Ai))
Space complexity: O(NlogN)