Open In App

Size of the smallest subset with maximum Bitwise OR

Improve
Improve
Like Article
Like
Save
Share
Report

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
Explanation: 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
Explanation: 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 the 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. 

  1. Find bitwise OR of all array elements. This is the OR we are looking for. 
  2. 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 the 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 the 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 returning the smallest size with the given OR) 

Implementation:

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












Complexity Analysis:

  • 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.

Implementation:

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))


C#




using System;
class GFG {
    // 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; i++) {
            for (int j = 0; j <= maxOR; j++) {
                count[i, j] = (int)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] = 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
    public static void Main()
    {
        int[] data = { 5, 1, 3, 4, 2 };
        int sz = 5;
        int maxOR = OR(data, sz);
 
        // Function Call
        Console.WriteLine(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












Complexity Analysis:

  • 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) 

Efficient approach : Space optimization

In previous approach the current value count[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.

Implementation steps:

  • Create a 1D vector count of size maxOR+1 and initialize it with 0.
  • Set a base case by initializing the values of count.
  • Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
  • Now Create a temporary 1d vector temp used to store the current values from previous computations.
  • After every iteration assign the value of temp to count for further iteration.
  • At last return and print the final answer stored in count[maxOR].

Implementation: 

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<int> count(maxOR + 1, 1e9);
 
    count[0] = 0;
 
    for (int i = 0; i < sz; i++) {
        vector<int> temp(maxOR + 1, 1e9);
 
        for (int j = 0; j <= maxOR; j++) {
            // Do not consider ith element.
            temp[j] = min(temp[j], count[j]);
 
            // Consider the ith element.
            if (count[j] != 1e9) {
                temp[j | data[i]] = min(
                    temp[j | data[i]], count[j] + 1);
            }
        }
 
        count = temp;
    }
 
    return count[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




import java.util.Arrays;
 
public class MinimumSubsetMaxOR {
    // Compute bitwise OR of all elements in the array
    static int OR(int[] data) {
        int mOR = 0;
        for (int i : data) {
            mOR |= i;
        }
        return mOR;
    }
 
    // Calculate the size of the minimum subset with maximum OR
    static int minSubset(int[] data, int maxOR) {
        int sz = data.length;
 
        // Create a table where count[i][j] represents the minimum size of the subset
        // till the ith element with an OR equal to j
        int[][] count = new int[sz + 1][maxOR + 1];
 
        for (int i = 0; i <= sz; i++) {
            Arrays.fill(count[i], Integer.MAX_VALUE);
        }
 
        count[0][0] = 0;
 
        for (int i = 1; i <= sz; i++) {
            for (int j = 0; j <= maxOR; j++) {
                // Do not consider the ith element
                count[i][j] = Math.min(count[i][j], count[i - 1][j]);
 
                // Consider the ith element
                if (count[i - 1][j] != Integer.MAX_VALUE) {
                    count[i][j | data[i - 1]] = Math.min(count[i][j | data[i - 1]], count[i - 1][j] + 1);
                }
            }
        }
 
        return count[sz][maxOR];
    }
 
    // Driver code
    public static void main(String[] args) {
        int[] data = { 5, 1, 3, 4, 2 };
        int maxOR = OR(data);
 
        // Function Call
        System.out.println(minSubset(data, maxOR));
    }
}


Python




def OR(data, sz):
    """
    Compute bitwise OR of all elements in an array of size sz.
    """
    mOR = 0
    for i in range(sz):
        mOR |= data[i]
    return mOR
 
def minSubset(data, sz, maxOR):
    """
    Calculate the size of the minimum subset with maximum OR.
    """
    # count table where count[i][j] is the minimum size subset till the ith
    # element whose OR is j
    count = [float('inf')] * (maxOR + 1)
    count[0] = 0
 
    for i in range(sz):
        temp = [float('inf')] * (maxOR + 1)
 
        for j in range(maxOR + 1):
            # Do not consider the ith element.
            temp[j] = min(temp[j], count[j])
 
            # Consider the ith element.
            if count[j] != float('inf'):
                temp[j | data[i]] = min(temp[j | data[i]], count[j] + 1)
 
        count = temp
 
    return count[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))


C#




using System;
 
class MinimumSubsetMaxOR
{
    // Compute bitwise OR of all elements in the array
    static int OR(int[] data)
    {
        int mOR = 0;
        foreach (int i in data)
        {
            mOR |= i;
        }
        return mOR;
    }
 
    // Calculate the size of the minimum subset with maximum OR
    static int MinSubset(int[] data, int maxOR)
    {
        int sz = data.Length;
 
        // Create a table where count[i][j] represents the minimum size of the subset
        // till the ith element with an OR equal to j
        int[,] count = new int[sz + 1, maxOR + 1];
 
        for (int i = 0; i <= sz; i++)
        {
            for (int j = 0; j <= maxOR; j++)
            {
                count[i, j] = int.MaxValue;
            }
        }
 
        count[0, 0] = 0;
 
        for (int i = 1; i <= sz; i++)
        {
            for (int j = 0; j <= maxOR; j++)
            {
                // Do not consider the ith element
                count[i, j] = Math.Min(count[i, j], count[i - 1, j]);
 
                // Consider the ith element
                if (count[i - 1, j] != int.MaxValue)
                {
                    count[i, j | data[i - 1]] = Math.Min(count[i, j | data[i - 1]],
                                                         count[i - 1, j] + 1);
                }
            }
        }
 
        return count[sz, maxOR];
    }
 
    // Driver code
    static void Main(string[] args)
    {
        int[] data = { 5, 1, 3, 4, 2 };
        int maxOR = OR(data);
 
        // Function Call
        Console.WriteLine(MinSubset(data, maxOR));
    }
}
 
// This code is contributed by shivamgupta0987654321


Javascript




// Function to compute bitwise OR of all elements in the array
function OR(data) {
    let mOR = 0;
    for (let i = 0; i < data.length; ++i) {
        mOR |= data[i];
    }
    return mOR;
}
 
// Function to calculate the minimum size of subset with maximum OR
function minSubset(data, maxOR) {
    // Create a vector 'count' where count[i] represents the minimum size of subset
    // till ith element whose OR is i.
    let count = new Array(maxOR + 1).fill(Infinity);
    count[0] = 0;
 
    for (let i = 0; i < data.length; i++) {
        // Create a temporary vector to hold the updated count for the current element
        let temp = new Array(maxOR + 1).fill(Infinity);
 
        for (let j = 0; j <= maxOR; j++) {
            // Do not consider the current element (data[i]) in the subset.
            temp[j] = Math.min(temp[j], count[j]);
 
            // Consider the current element (data[i]) in the subset and update the count.
            if (count[j] !== Infinity) {
                temp[j | data[i]] = Math.min(temp[j | data[i]], count[j] + 1);
            }
        }
 
        // Update the 'count' vector for the next iteration.
        count = temp;
    }
 
    // Return the minimum size of the subset with the maximum OR (at index maxOR).
    return count[maxOR];
}
 
// Driver code
const data = [5, 1, 3, 4, 2];
const maxOR = OR(data);
 
// Function Call
console.log(minSubset(data, maxOR));


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(maxOR) 

Using method 3: Backtracking Approach

Implementation steps:

  • Compute the bitwise or of all elements in array of size.
  • Write the recursive function to find the size of the smallest element
  • such that bitwise OR of that set is maximum possible.
  • If the current OR value is already equal to the maximum OR value, update the minimum subset size and return.
  • If we have already considered all the elements in the array, return without updating the minimum subset size.
  • Write the Backtracking step.
  • remove the current element from the subset and recurse.
  • include the current element in the subset and recurse.
  • Calculate the size of minimum subset with maximum or.
  • Recursive function to find the size of the smallest subset such that the Bitwise OR of that set is Maximum possible.
  • Last return and print.

Code implementation for above approach:

C++




#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;
}
 
// Recursive function
void minSubsetUtil(int data[], int sz, int ORval,
                   int currOR, int subsetSize, int& minSize)
{
    if (currOR == ORval) {
        minSize = min(minSize, subsetSize);
        return;
    }
 
    if (sz == 0) {
        return;
    }
 
    // Backtracking step:
    minSubsetUtil(data + 1, sz - 1, ORval, currOR,
                  subsetSize, minSize);
 
    minSubsetUtil(data + 1, sz - 1, ORval, currOR | data[0],
                  subsetSize + 1, minSize);
}
 
// Calculate the size of minimum subset with maximum or
int minSubset(int data[], int sz, int maxOR)
{
    int minSize = INT_MAX;
    int currOR = 0;
    int subsetSize = 0;
 
    minSubsetUtil(data, sz, maxOR, currOR, subsetSize,
                  minSize);
 
    return minSize;
}
 
// 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




public class MinSubsetMaxOr {
    // 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;
    }
 
    // Recursive function
    static void minSubsetUtil(int data[], int sz, int ORval,
                              int currOR, int subsetSize, int[] minSize) {
        if (currOR == ORval) {
            minSize[0] = Math.min(minSize[0], subsetSize);
            return;
        }
 
        if (sz == 0) {
            return;
        }
 
        // Backtracking step:
        minSubsetUtil(data, sz - 1, ORval, currOR, subsetSize, minSize);
        minSubsetUtil(data, sz - 1, ORval, currOR | data[sz - 1], subsetSize + 1, minSize);
    }
 
    // Calculate the size of minimum subset with maximum OR
    static int minSubset(int data[], int sz, int maxOR) {
        int[] minSize = { Integer.MAX_VALUE };
        int currOR = 0;
        int subsetSize = 0;
 
        minSubsetUtil(data, sz, maxOR, currOR, subsetSize, minSize);
 
        return minSize[0];
    }
 
    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));
    }
}


Python




# Compute bitwise or of all elements in array of size sz
def bitwise_or(data):
    result = 0
    for elem in data:
        result |= elem
    return result
 
# Recursive function
def min_subset_util(data, sz, OR_val, curr_OR, subset_size, min_size):
    if curr_OR == OR_val:
        min_size[0] = min(min_size[0], subset_size)
        return
 
    if sz == 0:
        return
 
    # Backtracking step
    min_subset_util(data[1:], sz - 1, OR_val, curr_OR, subset_size, min_size)
 
    min_subset_util(data[1:], sz - 1, OR_val, curr_OR | data[0], subset_size + 1, min_size)
 
# Calculate the size of the minimum subset with the maximum OR
def min_subset(data):
    sz = len(data)
    max_OR = bitwise_or(data)
 
    min_size = [float('inf')]  # Using a list to simulate passing by reference
 
    curr_OR = 0
    subset_size = 0
 
    min_subset_util(data, sz, max_OR, curr_OR, subset_size, min_size)
 
    return min_size[0]
 
# Driver code
if __name__ == "__main__":
    data = [5, 1, 3, 4, 2]
    max_OR = bitwise_or(data)
 
    # Function Call
    print(min_subset(data))


C#




using System;
 
class Program
{
    // Function to compute bitwise OR of all elements in an array
    static int OR(int[] data)
    {
        int mOR = 0;
        foreach (int element in data)
        {
            mOR |= element;
        }
        return mOR;
    }
 
    // Recursive function to calculate the minimum subset size
    static void MinSubsetUtil(int[] data, int sz, int ORval,
                              int currOR, int subsetSize, ref int minSize)
    {
        if (currOR == ORval)
        {
            minSize = Math.Min(minSize, subsetSize);
            return;
        }
 
        if (sz == 0)
        {
            return;
        }
 
        // Backtracking step:
        int[] subArray = new int[sz - 1];
        Array.Copy(data, 1, subArray, 0, sz - 1);
 
        MinSubsetUtil(subArray, sz - 1, ORval, currOR, subsetSize, ref minSize);
 
        MinSubsetUtil(subArray, sz - 1, ORval, currOR | data[0], subsetSize + 1, ref minSize);
    }
 
    // Function to calculate the size of the minimum subset with maximum OR
    static int MinSubset(int[] data, int maxOR)
    {
        int minSize = int.MaxValue;
        int currOR = 0;
        int subsetSize = 0;
 
        MinSubsetUtil(data, data.Length, maxOR, currOR, subsetSize, ref minSize);
 
        return minSize;
    }
 
    // Driver code
    static void Main()
    {
        int[] data = { 5, 1, 3, 4, 2 };
        int maxOR = OR(data);
 
        // Function Call
        Console.WriteLine(MinSubset(data, maxOR));
    }
}


Javascript




// Function to compute bitwise OR of all elements in an array
function OR(data) {
    let mOR = 0;
    for (let element of data) {
        mOR |= element;
    }
    return mOR;
}
 
// Recursive function to calculate the size of the minimum subset with maximum OR
function minSubsetUtil(data, sz, ORval, currOR, subsetSize, minSize) {
    if (currOR === ORval) {
        // If the current OR value matches the target OR value, update the minimum size
        minSize[0] = Math.min(minSize[0], subsetSize);
        return;
    }
 
    if (sz === 0) {
        // If we have considered all elements, return
        return;
    }
 
    // Backtracking step: try both including and excluding the first element
    let subArray = data.slice(1);
 
    // Recursive call without including the first element
    minSubsetUtil(subArray, sz - 1, ORval, currOR, subsetSize, minSize);
 
    // Recursive call including the first element
    minSubsetUtil(subArray, sz - 1, ORval, currOR | data[0], subsetSize + 1, minSize);
}
 
// Function to calculate the size of the minimum subset with maximum OR
function minSubset(data, maxOR) {
    let minSize = [Infinity]; // Using an array to store the minimum size
 
    let currOR = 0; // Current OR value
    let subsetSize = 0; // Size of the current subset
 
    // Start the recursive process
    minSubsetUtil(data, data.length, maxOR, currOR, subsetSize, minSize);
 
    return minSize[0]; // Return the minimum size found
}
 
const data = [5, 1, 3, 4, 2];
const maxOR = OR(data); // Calculate the maximum OR value of the array
 
// Function Call
console.log(minSubset(data, maxOR)); // Output the minimum subset size with maximum OR


Output

2












Time Complexity: O(2^N), where N is the size of the input array.
Auxiliary Space: O(N), where N is the size of the input array.



Last Updated : 30 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads