在给定 Array 的所有 K 大小子集中查找最大 AND 值
给定一个包含N个非负整数的数组arr[] ,任务是在所有长度为K的子集中找到最大的 AND 值。
例子:
Input: arr[] = {1, 6, 9, 7}, K = 1
Output: 9
Explanation: As only one element is allowed 9 is the greatest value that can be obtained.
Input: arr[] = {3, 3, 3}, K = 2
Output: 3
Input: arr[] = {7, 8, 9, 10, 11, 12}, K = 3
Output: 8
朴素方法:最简单的方法是生成所有可能的长度为K的子集,并在其中找到最大 AND 值子集。
时间复杂度: O(2 N . N)
辅助空间: O(N)
有效解决方案:任何位置的位的贡献大于其右侧所有位的组合贡献。这意味着位的重要性从左到右(MSB 到 LSB)。所以贪婪地尝试首先设置最左边的位并检查有助于这样做的数字。按照以下步骤找到具有最大 AND 值的长度K的子集:
- 考虑用数组中的所有值初始化这个最优集合。
- 迭代从i = 30 到 0 的所有位位置。
- 检查是否有超过K个数字在第 i 个位置设置位
- 如果有,用这些新的值集更新最优集(这不过是最优集的一个子集)
- 如果在任何迭代中子集的大小正好变为K ,则中断并返回该集合。
Note: It is also possible that there are more than K values in our set after all the iterations This will simply mean that there are some repeating numbers in set (So they will not affect the answer).
Here is one example that can be considered :
arr[] = {3, 3, 3 }, K = 2
ans = 3 & 3 = 3 (if this optimal set is printed using the below code the answer will be [3, 3, 3] which will not affect the maximum and of the subset)
下面是上述方法的实现:
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)