Skip to content
Related Articles

Related Articles

Size of the smallest subset with maximum Bitwise OR

View Discussion
Improve Article
Save Article
Like Article
  • Difficulty Level : Medium
  • Last Updated : 28 Jun, 2022

Given an array of positive integers. The task is to find the size of the smallest subset such that the Bitwise OR of that set is Maximum possible. 

Examples

Input : arr[] = {5, 1, 3, 4, 2}
Output : 2
7 is the maximum value possible of OR, 
5|2 = 7 and 5|3 = 7

Input : arr[] = {2, 6, 2, 8, 4, 5}
Output : 3
15 is the maximum value of OR and set
elements are 8, 6, 5 

Source: Sprinklr on Campus Internship 

Doing bitwise OR of a number with some value does not decrease its value. It either keeps the value same or increases. If we take a closer look at the problem we can notice that the maximum OR value that we can get is by doing bitwise OR of all array elements. But this includes all elements and here want to know the smallest subset. So we do the following. 
I) Find bitwise OR of all array elements. This is the OR we are looking for. 
II) Now we need to find the smallest subset with this bitwise OR. This problem is similar to the subset-sum problem, We can solve it in two ways : 

  1. We generate all subsets and return the smallest size with given OR
  2. We use Dynamic Programming to solve the problem. This solution is going to be very similar to Maximum size subset with given sum

The time complexity of the 1st solution is O(2n) and time complexity of the Dynamic Programming solution is O(OR * n) where OR is OR of all array elements and n is the size of the input array. 

Using Method 1 : (generating all subsets and return the smallest size with given OR) 

C++




// CPP Code for above approach
#include <bits/stdc++.h>
using namespace std;
 
// Compute bitwise or of all elements
// in array of size sz
int OR(int data[], int sz)
{
    int mOR = 0;
      for (int i = 0; i < sz; ++i) {
        mOR |= data[i];
    }
   
      return mOR;
}
 
// calculate the size of
// minimum subset with maximum or
int minSubset(int data[], int sz,int maxOR)
{
  // store the minimum size of
  // the subset with maximum OR
      int minSZ=sz;
   
      // generates all subsets
    for(int mask=0;mask<(1<<sz);mask++)
    {
      // stores the size of the current subset
      int curSZ=0;
      // stores the OR of all the elements
      // in the current subset
      int curOR=0;
        
      for(int i=0;i<sz;i++)
      {
        if(mask&(1<<i))
        {
          curSZ++;
          curOR|=data[i];
        }
      }
      if(curOR==maxOR)
        minSZ=min(minSZ,curSZ);
    }
   
  return minSZ;
}
 
// Driver code
int main()
{
    int data[] = { 5, 1, 3, 4, 2 };
    int sz = sizeof(data) / sizeof(0);
    int maxOR = OR(data, sz);
     
    // Function Call
    cout << minSubset(data, sz,maxOR) << '\n' ;
}

Java




// Java Program for above approach
import java.io.*;
import java.util.*;
 
class Solution
{
   
  // Compute bitwise or of all elements
  // in array of size sz
  private static int OR(int[] arr)
  {
    int mOR = 0;
    for (int i = 0; i < arr.length; ++i)
    {
      mOR |= arr[i];
    }
    return mOR;
  }
   
  // Recursively calculating the size of
  // minimum subset with maximum or
  private static int maxSubset(int[] arr, int i,
                int curOr, int curSize, int maxOr)
  {
       
    // If i is arr.length
    if (i == arr.length)
    {
       
      // If curOr is equal to maxOr
      if (curOr == maxOr)
      {
          return curSize;
      }
       
      // Return arr.length
      else
      {
          return arr.length;
      }
    }
     
    // Try the current element in the subset
    int take = maxSubset(arr, i + 1, curOr |
                          arr[i], curSize + 1, maxOr);
     
    // Skip the current element
    int notTake = maxSubset(arr, i + 1, curOr,
                                      curSize, maxOr);
     
     
    // Return minimum of take and notTake
    return Math.min(take, notTake);
  }
   
  // Driver Code
  public static void main(String[] args)
  {
    int[] data = {5, 1, 3, 4, 2};
     
    int maxOr = OR(data);
     
    // Function Call
    int maxSubsetSize = maxSubset(data, 0, 0, 0, maxOr);
    System.out.println(maxSubsetSize);
  }
}
 
// Code contributed by Abdelaziz EROUI

Python3




# Python3 Code for above approach
 
 
# Compute bitwise or of all elements
# in array of size sz
def OR(data, sz):
    mOR = 0
    for i in range(sz) :
        mOR |= data[i]
     
   
    return mOR
 
 
# calculate the size of
# minimum subset with maximum or
def minSubset(data, sz,maxOR):
  # store the minimum size of
  # the subset with maximum OR
    minSZ=sz
   
    # generates all subsets
    for mask in range(1<<sz):
        # stores the size of the current subset
        curSZ=0
        # stores the OR of all the elements
        # in the current subset
        curOR=0
 
        for i in range(sz):
            if(mask&(1<<i)):
                curSZ+=1
                curOR|=data[i]
         
       
        if(curOR==maxOR):
            minSZ=min(minSZ,curSZ)     
     
   
    return minSZ
 
 
# Driver code
if __name__ == '__main__':
    data =[5, 1, 3, 4, 2]
    sz = len(data)
    maxOR = OR(data, sz)
     
    # Function Call
    print(minSubset(data, sz,maxOR))

C#




// C# Program for above approach
using System;
class Solution
{
   
  // Compute bitwise or of all elements
  // in array of size sz
  private static int OR(int[] arr)
  {
    int mOR = 0;
    for (int i = 0; i < arr.Length; ++i)
    {
      mOR |= arr[i];
    }
    return mOR;
  }
   
  // Recursively calculating the size of
  // minimum subset with maximum or
  private static int maxSubset(int[] arr, int i,
                int curOr, int curSize, int maxOr)
  {
       
    // If i is arr.length
    if (i == arr.Length)
    {
       
      // If curOr is equal to maxOr
      if (curOr == maxOr)
      {
          return curSize;
      }
       
      // Return arr.length
      else
      {
          return arr.Length;
      }
    }
     
    // Try the current element in the subset
    int take = maxSubset(arr, i + 1, curOr |
                          arr[i], curSize + 1, maxOr);
     
    // Skip the current element
    int notTake = maxSubset(arr, i + 1, curOr,
                                      curSize, maxOr);
     
     
    // Return minimum of take and notTake
    return Math.Min(take, notTake);
  }
   
  // Driver Code
  static void Main()
  {
    int[] data = {5, 1, 3, 4, 2};
     
    int maxOr = OR(data);
     
    // Function Call
    int maxSubsetSize = maxSubset(data, 0, 0, 0, maxOr);
     Console.WriteLine(maxSubsetSize);
  }
}
 
// This code is contributed by SoumikMondal

Javascript




<script>
 
// JavaScript Program for above approach
 
// Compute bitwise or of all elements
  // in array of size sz
function OR(arr)
{
    let mOR = 0;
    for (let i = 0; i < arr.length; ++i)
    {
      mOR |= arr[i];
    }
    return mOR;
}
 
// Recursively calculating the size of
  // minimum subset with maximum or
function maxSubset(arr,i,curOr,curSize,maxOr)
{
    // If i is arr.length
    if (i == arr.length)
    {
        
      // If curOr is equal to maxOr
      if (curOr == maxOr)
      {
          return curSize;
      }
        
      // Return arr.length
      else
      {
          return arr.length;
      }
    }
      
    // Try the current element in the subset
    let take = maxSubset(arr, i + 1, curOr |
                          arr[i], curSize + 1, maxOr);
      
    // Skip the current element
    let notTake = maxSubset(arr, i + 1, curOr,
                                      curSize, maxOr);
      
      
    // Return minimum of take and notTake
    return Math.min(take, notTake);
}
 
// Driver Code
let data=[5, 1, 3, 4, 2];
let maxOr = OR(data);
 
// Function Call
let maxSubsetSize = maxSubset(data, 0, 0, 0, maxOr);
document.write(maxSubsetSize);
     
     
// This code is contributed by rag2127
 
</script>

Output

2

Time complexity: O(2n)
Auxiliary Space: O(n) 

Using Method 2: 

 We first find the OR of all elements of given array.Now we need to find the smallest subset with this bitwise OR.

To do so, use the similar DP approach as given in the subset sum problem. count[i][j] denotes the minimum size subset till ith element whose OR is j.

C++




// CPP Code for above approach
#include <bits/stdc++.h>
using namespace std;
 
// Compute bitwise or of all elements
// in array of size sz
int OR(int data[], int sz)
{
    int mOR = 0;
    for (int i = 0; i < sz; ++i) {
        mOR |= data[i];
    }
 
    return mOR;
}
 
// calculate the size of
// minimum subset with maximum or
int minSubset(int data[], int sz, int maxOR)
{
    // count table where
      // count[i][j] => minimum size subset till ith element
      // whose OR is j
    vector<vector<int> > count(sz + 1, vector<int>(maxOR + 1, 1e9));
   
    count[0][0] = 0;
 
    for (int i = 0; i < sz; i++) {
        for (int j = 0; j <= maxOR; j++) {
            // Do not consider ith element.
            count[i + 1][j] = min(count[i + 1][j], count[i][j]);
 
            // Consider the ith element.
            if (count[i][j] != 1e9) {
                count[i + 1][j | data[i]] = min(
                    count[i + 1][j | data[i]], count[i][j] + 1);
            }
        }
    }
 
    return count[sz][maxOR];
}
 
// Driver code
int main()
{
    int data[] = { 5, 1, 3, 4, 2 };
    int sz = sizeof(data) / sizeof(0);
    int maxOR = OR(data, sz);
 
    // Function Call
    cout << minSubset(data, sz, maxOR) << '\n';
}

Java




/*package whatever //do not write package name here */
 
import java.io.*;
import java.util.*;
 
class GFG {
  // Java Code for above approach
 
  // Compute bitwise or of all elements
  // in array of size sz
  static int OR(int data[], int sz)
  {
    int mOR = 0;
    for (int i = 0; i < sz; ++i) {
      mOR |= data[i];
    }
 
    return mOR;
  }
 
  // calculate the size of
  // minimum subset with maximum or
  static int minSubset(int data[], int sz, int maxOR)
  {
    // count table where
    // count[i][j] => minimum size subset till ith element
    // whose OR is j
    int count[][] = new int[sz + 1][maxOR + 1];
    for(int i=0;i<sz+1;i++){
      Arrays.fill(count[i],1000000000);
    }
 
    count[0][0] = 0;
 
    for (int i = 0; i < sz; i++) {
      for (int j = 0; j <= maxOR; j++) {
        // Do not consider ith element.
        count[i + 1][j] = Math.min(count[i + 1][j], count[i][j]);
 
        // Consider the ith element.
        if (count[i][j] != 1000000000) {
          count[i + 1][j | data[i]] = Math.min(
            count[i + 1][j | data[i]], count[i][j] + 1);
        }
      }
    }
 
    return count[sz][maxOR];
  }
 
  /* Driver program to test above function*/
  public static void main(String args[])
  {
    int data[] = { 5, 1, 3, 4, 2 };
    int sz = data.length;
    int maxOR = OR(data, sz);
 
    // Function Call
    System.out.println(minSubset(data, sz, maxOR));
  }
}
 
// This code is contributed by shinjanpatra.

Python3




# Python3 Code for above approach
 
 
# Compute bitwise or of all elements
# in array of size sz
def OR(data, sz):
    mOR = 0
    for i in range(sz):
        mOR |= data[i]
    return mOR
 
 
# calculate the size of
# minimum subset with maximum or
def minSubset(data, sz, maxOR):
    # count table where
      # count[i][j] => minimum size subset till ith element
      # whose OR is j
    count=[[1e9 for _ in range(maxOR+1)]for _ in range(sz+1)]
   
    count[0][0] = 0
 
    for i in range(sz) :
        for j in range(maxOR) :
            # Do not consider ith element.
            count[i + 1][j] = min(count[i + 1][j], count[i][j])
 
            # Consider the ith element.
            if (count[i][j] != 1e9) :
                count[i + 1][j | data[i]] = min(
                    count[i + 1][j | data[i]], count[i][j] + 1)
             
         
     
 
    return count[sz][maxOR]
 
 
# Driver code
if __name__ == '__main__':
    data = [5, 1, 3, 4, 2]
    sz = len(data)
    maxOR = OR(data, sz)
 
    # Function Call
    print(minSubset(data, sz, maxOR))

Javascript




<script>
 
// JavaScript Code for above approach
 
// Compute bitwise or of all elements
// in array of size sz
function OR(data, sz){
    let mOR = 0
    for(let i=0;i<sz;i++)
        mOR |= data[i]
    return mOR
}
 
// calculate the size of
// minimum subset with maximum or
function minSubset(data, sz, maxOR){
    // count table where
    // count[i][j] => minimum size subset till ith element
    // whose OR is j
    let count = new Array(sz+1).fill(0).map(()=>new Array(maxOR+1).fill(1e9));
 
    count[0][0] = 0
 
    for(let i=0;i<sz;i++){
        for(let j=0;j<maxOR;j++){
            // Do not consider ith element.
            count[i + 1][j] = Math.min(count[i + 1][j], count[i][j])
 
            // Consider the ith element.
            if (count[i][j] != 1e9)
                count[i + 1][j | data[i]] = Math.min(
                    count[i + 1][j | data[i]], count[i][j] + 1)
        }
    }           
 
    return count[sz][maxOR]
}
 
// Driver code
 
let data = [5, 1, 3, 4, 2]
let sz = data.length
let maxOR = OR(data, sz)
 
// Function Call
document.write(minSubset(data, sz, maxOR),"</br>")
 
// This code is contributed by shinjanpatra
 
</script>

Output

2

Time complexity: O(n*maxOR) where n is the size of the array and maxOR is the maximum or that can be obtained.
Auxiliary Space: O(n*maxOR) 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!