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

📅  最后修改于: 2021-09-22 09:46:22             🧑  作者: Mango

给定一个正整数数组。任务是找到最小子集的大小,使得该集合的按位 OR是最大可能的。

例子

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 来实现的。但这包括所有元素,这里想知道最小的子集。因此,我们执行以下操作。
I) 查找所有数组元素的按位或。这就是我们正在寻找的 OR。
II) 现在我们需要用这个按位或找到最小的子集。这个问题类似于子集和问题,我们可以通过两种方式解决它:

  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


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 contibuted by SoumikMondal


Javascript


输出
2

时间复杂度: O(2 n )

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程