Maximize Bitwise AND of first element with complement of remaining elements for any permutation of given Array
Last Updated :
07 Jun, 2021
Given an array arr[] consisting of N integers, the task is to find the maximum value of Bitwise AND of the first element with the complement of remaining elements for any permutation of this array, i.e.
A1 &(~A2) & (~A3) & ……& (~An)
Examples:
Input: arr[] = {1, 2, 4, 8, 16}
Output: 16
Explanation:
For the permutation {16, 1, 2, 4, 8}, the maximum value of the expression can be obtained.
Input: arr[] = {0, 2, 3, 4, 9, 8}
Output: 4
Explanation:
For the permutation {4, 8, 9, 3, 2, 0}, the maximum value of the expression can be obtained
Naive Approach: The simplest approach to solve the problem is to generate all possible permutations of the given array and find the required value for each permutation and print the maximum among them.
Time Complexity: O(N * N!)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by the following observation:
- The expression A1 &(~A2) & (~A3) & …… & (~An) is solely dependent on the value of A1.
- Therefore, to get the maximize the value from the expression, choose A1 such that it has the set bit of as highest significance as possible, which is unset in all other array elements.
- Since, the order of remaining array elements doesn’t matter, print any permutation having the obtained A1 as the first element.
Illustration:
For arr[] = {1, 2, 4, 8, 16}
Binary representation of the array elements:
(16)10 = (10000)2
(8)10 = (01000)2
(4)10 = (00100)2
(2)10 = (00010)2
(1)10 = (00001)2
As it can be seen that 16 has the highest significant set bit which is unset in all other array elements. Therefore, the required permutation of given permutation will contain 16 as the first element.
Hence, the required Bitwise AND is maximum for permutation having 16 as the first element, which is equal to 16 in this case.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define size_int 32
int functionMax( int arr[], int n)
{
vector< int > setBit[32];
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < size_int; j++) {
if (arr[i] & (1 << j))
setBit[j].push_back(i);
}
}
for ( int i = size_int; i >= 0; i--) {
if (setBit[i].size() == 1) {
swap(arr[0], arr[setBit[i][0]]);
break ;
}
}
int maxAnd = arr[0];
for ( int i = 1; i < n; i++) {
maxAnd = maxAnd & (~arr[i]);
}
return maxAnd;
}
int main()
{
int arr[] = { 1, 2, 4, 8, 16 };
int n = sizeof arr / sizeof arr[0];
cout << functionMax(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static final int size_int = 32 ;
static int functionMax( int arr[], int n)
{
Vector<Integer> []setBit = new Vector[ 32 + 1 ];
for ( int i = 0 ; i < setBit.length; i++)
setBit[i] = new Vector<Integer>();
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < size_int; j++)
{
if ((arr[i] & ( 1 << j)) > 0 )
setBit[j].add(i);
}
}
for ( int i = size_int; i >= 0 ; i--)
{
if (setBit[i].size() == 1 )
{
swap(arr, 0 , setBit[i].get( 0 ));
break ;
}
}
int maxAnd = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
{
maxAnd = maxAnd & (~arr[i]);
}
return maxAnd;
}
static int [] swap( int []arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return arr;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 4 , 8 , 16 };
int n = arr.length;
System.out.print(functionMax(arr, n));
}
}
|
Python3
def functionMax(arr, n):
setBit = [[] for i in range ( 32 )]
for i in range (n):
for j in range ( 32 ):
if (arr[i] & ( 1 << j)):
setBit[j].append(i)
i = 31
while (i > = 0 ):
if ( len (setBit[i]) = = 1 ):
temp = arr[ 0 ]
arr[ 0 ] = arr[setBit[i][ 0 ]]
arr[setBit[i][ 0 ]] = temp
break
i - = 1
maxAnd = arr[ 0 ]
for i in range ( 1 , n, 1 ):
maxAnd = (maxAnd & (~arr[i]))
return maxAnd
if __name__ = = '__main__' :
arr = [ 1 , 2 , 4 , 8 , 16 ]
n = len (arr)
print (functionMax(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static readonly int size_int = 32;
static int functionMax( int []arr, int n)
{
List< int > []setBit = new List< int >[32 + 1];
for ( int i = 0; i < setBit.Length; i++)
setBit[i] = new List< int >();
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < size_int; j++)
{
if ((arr[i] & (1 << j)) > 0)
setBit[j].Add(i);
}
}
for ( int i = size_int; i >= 0; i--)
{
if (setBit[i].Count == 1)
{
swap(arr, 0, setBit[i][0]);
break ;
}
}
int maxAnd = arr[0];
for ( int i = 1; i < n; i++)
{
maxAnd = maxAnd & (~arr[i]);
}
return maxAnd;
}
static int [] swap( int []arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return arr;
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 4, 8, 16 };
int n = arr.Length;
Console.Write(functionMax(arr, n));
}
}
|
Javascript
<script>
var size_int = 32;
function functionMax( arr, n)
{
var setBit = Array.from(Array(32), ()=> new Array());
for ( var i = 0; i < n; i++) {
for ( var j = 0; j < size_int; j++) {
if (arr[i] & (1 << j))
setBit[j].push(i);
}
}
for ( var i = size_int-1; i >= 0; i--) {
if (setBit[i].length == 1) {
[arr[0], arr[setBit[i][0]]] = [arr[setBit[i][0]], arr[0]];
break ;
}
}
var maxAnd = arr[0];
for ( var i = 1; i < n; i++) {
maxAnd = maxAnd & (~arr[i]);
}
return maxAnd;
}
var arr = [1, 2, 4, 8, 16];
var n = arr.length;
document.write( functionMax(arr, n));
</script>
|
Time Complexity: O(N * sizeof(int)), where sizeof(int) is 32
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...