Maximum Bitwise AND value of subsequence of length K
Last Updated :
28 Mar, 2023
Given an array a of size N and an integer K. The task is to find the maximum bitwise and value of elements of any subsequence of length K.
Note: a[i] <= 109
Examples:
Input: a[] = {10, 20, 15, 4, 14}, K = 4
Output: 4
{20, 15, 4, 14} is the subsequence with highest ‘&’ value.
Input: a[] = {255, 127, 31, 5, 24, 37, 15}, K = 5
Output: 8
Naive Approach: A naive approach is to recursively find the bitwise and value of all subsequences of length K and the maximum among all of them will be the answer.
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > v;
void subsequence( int arr[], int index, vector< int >& subarr,
int n, int k)
{
if (index == n) {
if (subarr.size() == k) {
int ans = subarr[0];
for ( auto it : subarr) {
ans = ans & it;
}
v.push_back(ans);
}
return ;
}
else {
subarr.push_back(arr[index]);
subsequence(arr, index + 1, subarr, n, k);
subarr.pop_back();
subsequence(arr, index + 1, subarr, n, k);
}
}
int main()
{
int arr[] = { 255, 127, 31, 5, 24, 37, 15 };
int n = sizeof (arr) / sizeof (arr[0]);
int k = 5;
vector< int > vec;
subsequence(arr, 0, vec, n, k);
cout << *max_element(v.begin(), v.end());
return 0;
}
|
Java
import java.util.*;
class Main {
static ArrayList<Integer> v = new ArrayList<Integer>();
static void subsequence( int [] arr, int index,
ArrayList<Integer> subarr,
int n, int k)
{
if (index == n) {
if (subarr.size() == k) {
int ans = subarr.get( 0 );
for ( int it : subarr) {
ans = ans & it;
}
v.add(ans);
}
return ;
}
else {
subarr.add(arr[index]);
subsequence(arr, index + 1 , subarr, n, k);
subarr.remove(subarr.size() - 1 );
subsequence(arr, index + 1 , subarr, n, k);
}
}
public static void main(String[] args)
{
int [] arr = { 255 , 127 , 31 , 5 , 24 , 37 , 15 };
int n = arr.length;
int k = 5 ;
ArrayList<Integer> vec = new ArrayList<Integer>();
subsequence(arr, 0 , vec, n, k);
System.out.println(Collections.max(v));
}
}
|
Python3
import itertools
v = []
def subsequence(arr, index, subarr, n, k):
if index = = n:
if len (subarr) = = k:
ans = subarr[ 0 ]
for i in range ( 1 , len (subarr)):
ans & = subarr[i]
v.append(ans)
return
else :
subarr.append(arr[index])
subsequence(arr, index + 1 , subarr, n, k)
subarr.pop()
subsequence(arr, index + 1 , subarr, n, k)
if __name__ = = "__main__" :
arr = [ 255 , 127 , 31 , 5 , 24 , 37 , 15 ]
n = len (arr)
k = 5
vec = []
subsequence(arr, 0 , vec, n, k)
print ( max (v))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static List< int > v = new List< int >();
static void subsequence( int [] arr, int index,
List< int > subarr, int n, int k)
{
if (index == n)
{
if (subarr.Count==k){
int ans=subarr[0];
foreach ( int it in subarr){
ans &= it;
}
v.Add(ans);
}
return ;
}
else
{
subarr.Add(arr[index]);
subsequence(arr, index + 1, subarr,n,k);
subarr.RemoveAt(subarr.Count-1);
subsequence(arr, index + 1, subarr,n,k);
}
}
static void Main()
{
int [] arr={ 255, 127, 31, 5, 24, 37 ,15};
int n=arr.Length;
int k=5;
List< int > vec = new List< int >();
subsequence(arr, 0, vec,n,k);
Console.WriteLine(v.Max());
}
}
|
Javascript
let v = [];
function subsequence(arr, index, subarr, n, k)
{
if (index == n) {
if (subarr.length == k) {
let ans = subarr[0];
for (let i = 1; i < subarr.length; i++) {
ans &= subarr[i];
}
v.push(ans);
}
return ;
} else {
subarr.push(arr[index]);
subsequence(arr, index + 1, subarr, n, k);
subarr.pop();
subsequence(arr, index + 1, subarr, n, k);
}
}
let arr = [255, 127, 31, 5, 24, 37, 15];
let n = arr.length;
let k = 5;
let vec = [];
subsequence(arr, 0, vec, n, k);
console.log(Math.max(...v));
|
Time Complexity: O(k*(2^n)) where k is the maximum subsequence length and n is the size of the array.
Auxiliary space: O(2^n) where n is the size of the array.
Approach 1: An efficient approach is to solve it using bit properties. Below are the steps to solve the problem:
- Iterate from the left(initially left = 31 as 232 > 109 ) till we find > K numbers in the vector temp (initially temp = arr) whose i-th bit is set. Update the new set of numbers to temp array
- If we do not get > K numbers, the & value of any K elements in the temp array will be the maximum & value possible.
- Repeat Step-1 with left re-initialized as first-bit + 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > findSubset(vector< int >& temp, int & last, int k)
{
vector< int > ans;
for ( int i = last; i >= 0; i--) {
int cnt = 0;
for ( auto it : temp) {
int bit = it & (1 << i);
if (bit > 0)
cnt++;
}
if (cnt >= k) {
for ( auto it : temp) {
int bit = it & (1 << i);
if (bit > 0)
ans.push_back(it);
}
last = i - 1;
return ans;
}
}
return ans;
}
int findMaxiumAnd( int a[], int n, int k)
{
int last = 31;
vector< int > temp1, temp2;
for ( int i = 0; i < n; i++) {
temp2.push_back(a[i]);
}
while (( int )temp2.size() >= k) {
temp1 = temp2;
temp2 = findSubset(temp2, last, k);
}
int ans = temp1[0];
for ( int i = 0; i < k; i++)
ans = ans & temp1[i];
return ans;
}
int main()
{
int a[] = { 255, 127, 31, 5, 24, 37, 15 };
int n = sizeof (a) / sizeof (a[0]);
int k = 4;
cout << findMaxiumAnd(a, n, k);
}
|
Java
import java.util.*;
class GFG
{
static int last;
static Vector<Integer>
findSubset(Vector<Integer> temp, int k)
{
Vector<Integer> ans = new Vector<Integer>();
for ( int i = last; i >= 0 ; i--)
{
int cnt = 0 ;
for (Integer it : temp)
{
int bit = it & ( 1 << i);
if (bit > 0 )
cnt++;
}
if (cnt >= k)
{
for (Integer it : temp)
{
int bit = it & ( 1 << i);
if (bit > 0 )
ans.add(it);
}
last = i - 1 ;
return ans;
}
}
return ans;
}
static int findMaxiumAnd( int a[], int n, int k)
{
last = 31 ;
Vector<Integer> temp1 = new Vector<Integer>();
Vector<Integer> temp2 = new Vector<Integer>();;
for ( int i = 0 ; i < n; i++)
{
temp2.add(a[i]);
}
while (( int )temp2.size() >= k)
{
temp1 = temp2;
temp2 = findSubset(temp2, k);
}
int ans = temp1.get( 0 );
for ( int i = 0 ; i < k; i++)
ans = ans & temp1.get(i);
return ans;
}
public static void main(String[] args)
{
int a[] = { 255 , 127 , 31 , 5 , 24 , 37 , 15 };
int n = a.length;
int k = 4 ;
System.out.println(findMaxiumAnd(a, n, k));
}
}
|
Python3
last = 31
def findSubset(temp, k):
global last
ans = []
for i in range (last, - 1 , - 1 ):
cnt = 0
for it in temp:
bit = it & ( 1 << i)
if (bit > 0 ):
cnt + = 1
if (cnt > = k):
for it in temp:
bit = it & ( 1 << i)
if (bit > 0 ):
ans.append(it)
last = i - 1
return ans
return ans
def findMaxiumAnd(a, n, k):
global last
temp1, temp2, = [], []
for i in range (n):
temp2.append(a[i])
while len (temp2) > = k:
temp1 = temp2
temp2 = findSubset(temp2, k)
ans = temp1[ 0 ]
for i in range (k):
ans = ans & temp1[i]
return ans
a = [ 255 , 127 , 31 , 5 , 24 , 37 , 15 ]
n = len (a)
k = 4
print (findMaxiumAnd(a, n, k))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int last;
static List< int >findSubset(List< int > temp, int k)
{
List< int > ans = new List< int >();
for ( int i = last; i >= 0; i--)
{
int cnt = 0;
foreach ( int it in temp)
{
int bit = it & (1 << i);
if (bit > 0)
cnt++;
}
if (cnt >= k)
{
foreach ( int it in temp)
{
int bit = it & (1 << i);
if (bit > 0)
ans.Add(it);
}
last = i - 1;
return ans;
}
}
return ans;
}
static int findMaxiumAnd( int []a, int n, int k)
{
last = 31;
List< int > temp1 = new List< int >();
List< int > temp2 = new List< int >();;
for ( int i = 0; i < n; i++)
{
temp2.Add(a[i]);
}
while (( int )temp2.Count >= k)
{
temp1 = temp2;
temp2 = findSubset(temp2, k);
}
int ans = temp1[0];
for ( int i = 0; i < k; i++)
ans = ans & temp1[i];
return ans;
}
public static void Main(String[] args)
{
int []a = { 255, 127, 31, 5, 24, 37, 15 };
int n = a.Length;
int k = 4;
Console.WriteLine(findMaxiumAnd(a, n, k));
}
}
|
Javascript
<script>
function findSubset(temp,k)
{
let ans = [];
for (let i = last; i >= 0; i--)
{
let cnt = 0;
for (let it=0;it< temp.length;it++)
{
let bit = temp[it] & (1 << i);
if (bit > 0)
cnt++;
}
if (cnt >= k)
{
for (let it=0;it< temp.length;it++)
{
let bit = temp[it] & (1 << i);
if (bit > 0)
ans.push(temp[it]);
}
last = i - 1;
return ans;
}
}
return ans;
}
function findMaxiumAnd(a,n,k)
{
last = 31;
let temp1 = [];
let temp2 = [];
for (let i = 0; i < n; i++)
{
temp2.push(a[i]);
}
while (temp2.length >= k)
{
temp1 = temp2;
temp2 = findSubset(temp2, k);
}
let ans = temp1[0];
for (let i = 0; i < k; i++)
ans = ans & temp1[i];
return ans;
}
let a=[255, 127, 31, 5, 24, 37, 15 ];
let n = a.length;
let k = 4;
document.write(findMaxiumAnd(a, n, k));
</script>
|
Time Complexity: O(N*N), as we are using a loop to traverse N times and in each traversal we are calling the findSubset function which will cost O (N) time. Where N is the number of elements in the array.
Auxiliary Space: O(N), as we are using extra space for the temp array. Where N is the number of elements in the array.
Approach 2:
The idea is based on the property of AND operator. AND operation of any two bits
results in 1 if both bits are 1 else if any bit is 0 then result is 0. So We start
from the MSB and check whether we have a minimum of K elements of array having set
value. If yes then that MSB will be part of our solution and be added to result
otherwise we will discard that bit. Similarly,iterating from MSB to LSB (32 to 1) for
bit position we can easily check which bit will be part of our solution and will keep
adding all such bits to our solution.
Following are the steps to implement above idea :
- Initialize result variable with 0 .
- Run a outer for loop from j : 31 to 0 (for every bit)
- Initialize temporary variable with ( res | (1<<j) ) .
- Initialize count variable with 0 .
- Run a inner for loop from i : 0 to n-1 and check
- if ( ( temporary & A[i] ) == temporary ) then count++ .
- After inner for loop gets over then check :
- if ( count >= K ) then update result with temporary .
- After outer for loops ends return result .
- Print result .
Below is the code for above approach .
C++
#include <bits/stdc++.h>
using namespace std;
int max_and( int N, vector< int >& A, int K)
{
int result = 0;
for ( int j = 31; j >= 0; j--) {
int temp = (result | (1 << j));
int count = 0;
for ( int j = 0; j < N; j++) {
if ((temp & A[j]) == temp) {
count++;
}
}
if (count >= K) {
result = temp;
}
}
return result;
}
int main()
{
vector< int > A = { 255, 127, 31, 5, 24, 37 ,15 };
int N = 7;
int K = 4;
cout
<< "Maximum AND of subsequence of A of size K is : "
<< max_and(N, A, K);
return 0;
}
|
Java
import java.util.*;
class Main {
public static int max_and( int N, ArrayList<Integer> A, int K) {
int result = 0 ;
for ( int j = 31 ; j >= 0 ; j--) {
int temp = (result | ( 1 << j));
int count = 0 ;
for ( int i = 0 ; i < N; i++) {
if ((temp & A.get(i)) == temp) {
count++;
}
}
if (count >= K) {
result = temp;
}
}
return result;
}
public static void main(String[] args) {
ArrayList<Integer> A = new ArrayList<Integer>(Arrays.asList( 255 , 127 , 31 , 5 , 24 , 37 , 15 ));
int N = 7 ;
int K = 4 ;
System.out.println( "Maximum AND of subsequence of A of size K is : " + max_and(N, A, K));
}
}
|
Python3
def max_and(N, A, K):
result = 0
for j in range ( 31 , - 1 , - 1 ):
temp = (result | ( 1 << j))
count = 0
for j in range (N):
if (temp & A[j]) = = temp:
count = count + 1
if count > = K:
result = temp
return result
A = [ 255 , 127 , 31 , 5 , 24 , 37 , 15 ]
N = 7
K = 4
print ( "Maximum AND of subsequence of A of size K is : " , max_and(N, A, K))
|
Javascript
function max_and(N, A, K)
{
let result = 0;
for (let j = 31; j >= 0; j--)
{
let temp = (result | (1 << j));
let count = 0;
for (let j = 0; j < N; j++)
{
if ((temp & A[j]) == temp) {
count = count + 1;
}
}
if (count >= K)
{
result = temp;
}
}
return result;
}
let A = [ 255, 127, 31, 5, 24, 37 ,15 ];
let N = 7;
let K = 4;
console.log( "Maximum AND of subsequence of A of size K is : " , max_and(N, A, K));
|
C#
using System;
class GFG
{
static int findMaxiumAnd( int []a, int n, int k)
{
int result = 0;
for ( int j = 31; j >= 0; j--) {
int temp = (result | (1 << j));
int count = 0;
for ( int i = 0; i < n; i++) {
if ((temp & a[i]) == temp) {
count++;
}
}
if (count >= k) {
result = temp;
}
}
return result;
}
public static void Main(String[] args)
{
int []a = { 255, 127, 31, 5, 24, 37, 15 };
int n = a.Length;
int k = 4;
Console.WriteLine(findMaxiumAnd(a, n, k));
}
}
|
Output
Maximum AND of subsequence of A of size K is : 24
Time Complexity: O(32*N): where N is the size of Array A
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...