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)
Similar Reads
Maximum Sum Subsequence of length k
Given an array sequence [A1, A2 ...An], the task is to find the maximum possible sum of increasing subsequence S of length k such that S1<=S2<=S3.........<=Sk. Examples: Input : n = 8 k = 3 A=[8 5 9 10 5 6 21 8] Output : 40 Possible Increasing subsequence of Length 3 with maximum possible s
11 min read
Maximum sum subsequence of length K | Set 2
Given an array sequence arr[] i.e [A1, A2 â¦An] and an integer k, the task is to find the maximum possible sum of increasing subsequence S of length k such that S1<=S2<=S3â¦â¦â¦<=Sk. Examples: Input: arr[] = {-1, 3, 4, 2, 5}, K = 3Output: 3 4 5Explanation: Subsequence 3 4 5 with sum 12 is the s
7 min read
Find subsequences with maximum Bitwise AND and Bitwise OR
Given an array of n elements. The task is to print the maximum sum by selecting two subsequences of the array (not necessarily different) such that the sum of bitwise AND of all elements of the first subsequence and bitwise OR of all the elements of the second subsequence is maximum. Examples: Input
4 min read
Maximum length subsequence possible of the form R^N K^N
Given a string containing only two characters i.e. R and K (like RRKRRKKKKK). The task is to find the maximum value of N for a subsequence possible of the form R---N times and then K---N times (i.e. of the form R^N K^N). Note: String of k should be started after the string of R i.e. first k that wou
6 min read
Find minimum length for Maximum Mex Subsequence
Given an array A[] consisting of N integers. You have to choose a subsequence from the given array such that the mex of that chosen subsequence is maximum. The task is to return the minimum length of such subsequence. Examples: Input: N = 7, A[] = {1, 2, 1, 2, 1, 4, 0}Output: 3Explanation: We can ch
4 min read
Longest subsequence with a given AND value | O(N)
Given an array arr[], the task is to find the longest subsequence with a given AND value M. If there is no such sub-sequence then print 0.Examples: Input: arr[] = {3, 7, 2, 3}, M = 3 Output: 3 {3, 7, 3} is the required subsequence. 3 & 7 & 3 = 3Input: arr[] = {2, 2}, M = 3 Output: 0 Naive ap
5 min read
Count of subsequences having maximum distinct elements
Given an arr of size n. The problem is to count all the subsequences having maximum number of distinct elements. Examples: Input : arr[] = {4, 7, 6, 7} Output : 2 The indexes for the subsequences are: {0, 1, 2} - Subsequence is {4, 7, 6} and {0, 2, 3} - Subsequence is {4, 6, 7} Input : arr[] = {9, 6
5 min read
Longest subsequence having maximum sum
Given an array arr[] of size N, the task is to find the longest non-empty subsequence from the given array whose sum is maximum. Examples: Input: arr[] = { 1, 2, -4, -2, 3, 0 } Output: 1 2 3 0 Explanation: Sum of elements of the subsequence {1, 2, 3, 0} is 6 which is the maximum possible sum. Theref
8 min read
Number of K length subsequences with minimum sum
Given an array arr[] of size N and an integer K, the task is to find the number of K length subsequences of this array such that the sum of these subsequences is the minimum possible. Examples: Input: arr[] = {1, 2, 3, 4}, K = 2 Output: 1 Subsequences of length 2 are (1, 2), (1, 3), (1, 4), (2, 3),
8 min read
Maximum sum alternating subsequence
Given an array, the task is to find sum of maximum sum alternating subsequence starting with first element. Here alternating sequence means first decreasing, then increasing, then decreasing, ... For example 10, 5, 14, 3 is an alternating sequence. Note that the reverse type of sequence (increasing
13 min read