📌  相关文章
📜  在给定 Array 的所有 K 大小子集中查找最大 AND 值

📅  最后修改于: 2022-05-13 01:56:05.503000             🧑  作者: Mango

在给定 Array 的所有 K 大小子集中查找最大 AND 值

给定一个包含N个非负整数的数组arr[] ,任务是在所有长度为K的子集中找到最大的 AND 值。

例子:

朴素方法:最简单的方法是生成所有可能的长度为K的子集,并在其中找到最大 AND 值子集。

时间复杂度: O(2 N . N)
辅助空间: O(N)

有效解决方案:任何位置的位的贡献大于其右侧所有位的组合贡献。这意味着位的重要性从左到右(MSB 到 LSB)。所以贪婪地尝试首先设置最左边的位并检查有助于这样做的数字。按照以下步骤找到具有最大 AND 值的长度K的子集:

  1. 考虑用数组中的所有值初始化这个最优集合。
  2. 迭代从i = 30 到 0 的所有位位置。
  3. 检查是否有超过K个数字在第 i 个位置设置位
  4. 如果有,用这些新的值集更新最优集(这不过是最优集的一个子集)
  5. 如果在任何迭代中子集的大小正好变为K ,则中断并返回该集合。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the maximum AND
// value of all the subsets having length K
int maxAndSubset(int arr[], int N, int K)
{
    // Intitalizing the optimal_set
    vector optimal_set(arr, arr + N);
 
    // Iterating for every position of bits
    for (int j = 30; j >= 0; j--) {
        vector new_optimal_set;
 
        // Checking if the bits at jth
        // position can be obtained set
        // among the numbers available
        // from optimal_set set
        for (auto element : optimal_set) {
            if ((1 << j) & element) {
 
                // If bit set at position j,
                // add into new_optimal_set
                new_optimal_set.push_back(element);
            }
        }
        if (new_optimal_set.size() < K)
            continue;
 
        // Updating optimal_set with new_optimal_set
        optimal_set = new_optimal_set;
        if (optimal_set.size() == K)
            break;
    }
 
    int ans = (1 << 30) - 1;
 
    for (auto element : optimal_set) {
        ans &= element;
    }
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 7, 8, 9, 10, 11, 12 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 3;
    cout << maxAndSubset(arr, N, K);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
public class GFG
{
 
  // Function to find the maximum AND
  // value of all the subsets having length K
  static int maxAndSubset(int arr[], int N, int K)
  {
     
    // Intitalizing the optimal_set
    ArrayList optimal_set = new ArrayList(N);
    for(int i = 0; i < N; i++){
      optimal_set.add(arr[i]);
    }
 
    // Iterating for every position of bits
    for (int j = 30; j >= 0; j--) {
      ArrayList new_optimal_set = new ArrayList();
 
      // Checking if the bits at jth
      // position can be obtained set
      // among the numbers available
      // from optimal_set set
      for (int element : optimal_set) {
        if (((1 << j) & element) == 0) {
 
          // If bit set at position j,
          // add into new_optimal_set
          new_optimal_set.add(element);
        }
      }
      if (new_optimal_set.size() < K)
        continue;
 
      // Updating optimal_set with new_optimal_set
      optimal_set = new_optimal_set;
      if (optimal_set.size() == K)
        break;
    }
 
    int ans = (1 << 30) - 1;
 
    for (int element : optimal_set) {
      ans &= element;
    }
    return ans;
  }
 
  // Driver Code
  public static void main(String args[])
  {
    int arr[] = { 7, 8, 9, 10, 11, 12 };
    int N = arr.length;
    int K = 3;
    System.out.println(maxAndSubset(arr, N, K));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python3
# python3 program for the above approach
 
# Function to find the maximum AND
# value of all the subsets having length K
def maxAndSubset(arr, N, K):
 
    # Intitalizing the optimal_set
    optimal_set = arr.copy()
 
    # Iterating for every position of bits
    for j in range(30, -1, -1):
        new_optimal_set = []
 
        # Checking if the bits at jth
        # position can be obtained set
        # among the numbers available
        # from optimal_set set
        for element in optimal_set:
            if ((1 << j) & element):
 
                # If bit set at position j,
                # add into new_optimal_set
                new_optimal_set.append(element)
 
        if (len(new_optimal_set) < K):
            continue
 
        # Updating optimal_set with new_optimal_set
        optimal_set = new_optimal_set
        if (len(optimal_set) == K):
            break
 
    ans = (1 << 30) - 1
 
    for element in optimal_set:
        ans &= element
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    arr = [7, 8, 9, 10, 11, 12]
    N = len(arr)
    K = 3
    print(maxAndSubset(arr, N, K))
 
  # This code is contributed by rakeshsahni


C#
// C# program for the above approach
using System;
using System.Collections;
class GFG
{
 
  // Function to find the maximum AND
  // value of all the subsets having length K
  static int maxAndSubset(int []arr, int N, int K)
  {
     
    // Intitalizing the optimal_set
    ArrayList optimal_set = new ArrayList(N);
    for(int i = 0; i < N; i++){
      optimal_set.Add(arr[i]);
    }
 
    // Iterating for every position of bits
    for (int j = 30; j >= 0; j--) {
      ArrayList new_optimal_set = new ArrayList();
 
      // Checking if the bits at jth
      // position can be obtained set
      // among the numbers available
      // from optimal_set set
      foreach (int element in optimal_set) {
        if (((1 << j) & element) == 0) {
 
          // If bit set at position j,
          // add into new_optimal_set
          new_optimal_set.Add(element);
        }
      }
      if (new_optimal_set.Count < K)
        continue;
 
      // Updating optimal_set with new_optimal_set
      optimal_set = new_optimal_set;
      if (optimal_set.Count == K)
        break;
    }
 
    int ans = (1 << 30) - 1;
 
    foreach (int element in optimal_set) {
      ans &= element;
    }
    return ans;
  }
 
  // Driver Code
  public static void Main()
  {
    int []arr = { 7, 8, 9, 10, 11, 12 };
    int N = arr.Length;
    int K = 3;
    Console.WriteLine(maxAndSubset(arr, N, K));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出:
8

时间复杂度: O(32 * N)
辅助空间: O(N)