📌  相关文章
📜  具有最大按位或的最小子集的大小

📅  最后修改于: 2021-04-24 03:22:21             🧑  作者: Mango

给定正整数数组。任务是找到最小子集的大小,以使该集合的按位或为最大可能值。

例子

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 

资料来源:Sprinklr在校园实习

对某个值与某个数字进行按位“或”运算不会减小其值。它要么保持值不变,要么增加值。如果我们仔细研究这个问题,我们会注意到,我们可以通过对所有数组元素进行按位“或”运算来获得最大OR值。但这包括所有元素,在这里想知道最小的子集。因此,我们执行以下操作。
我)找到所有数组元素的按位或。这是我们正在寻找的OR。
II)现在,我们需要找到具有此按位OR的最小子集。这个问题类似于子集和问题,我们可以通过两种方式解决它:

  1. 我们递归地生成所有子集,并在给定OR的情况下返回最小的子集
  2. 我们使用动态编程来解决该问题。该解决方案将非常类似于具有给定总和的“最大大小”子集

递归解决方案的时间复杂度为O(2 n ),动态编程解决方案的时间复杂度为O(OR * n),其中OR为所有数组元素的OR,n为输入数组的大小。

使用方法1 :(递归生成所有子集,并在给定OR下返回最小大小)

C++
// CPP Code for above approach
#include 
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;
}
 
// Recursively calculating the size of
// minimum subset with maximum or
void minSubset(int data[], int sz, int pos, int len,
               int subset[], int req, int& ans)
{
     
    // checking the conditions for maxOR in the
    // resultant subset and setting len strictly
    // above 0
    if (pos == sz && OR(subset, len) == req &&
                                        len > 0)
    {
      
        ans = min(len, ans);
    }
    else if (pos < sz)
    {
        
        // Try the current element in the subset.
        subset[len] = data[pos];
        minSubset(data, sz, pos + 1, len + 1, subset,
                                            req, ans);
 
        // Skip the current element.
        minSubset(data, sz, pos + 1, len, subset,
                                            req, ans);
    }
}
 
// Driver code
int main()
{
    int data[] = { 5, 1, 3, 4, 2 };
    int sz = sizeof(data) / sizeof(0);
    int req = OR(data, sz);
    int ans = sz;
 
    // Creating a temporary subset with
    // all elements 0
    int subset[sz];
     
    // Function Call
    minSubset(data, sz, 0, 0, subset, req, ans);
    cout << ans;
}
 
// Code contibuted by Adhiraj Singh


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 contibuted by Abdelaziz EROUI


输出
2

时间复杂度: O(2 n )