📌  相关文章
📜  求 K 大小子数组的按位与和按位或的最大乘积

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

求 K 大小子数组的按位与和按位或的最大乘积

给定一个包含N个整数和一个整数K的数组arr[] ,任务是找到K大小子数组的所有元素的按位与按位或的乘积的最大值。

例子:

方法:给定的问题可以使用滑动窗口技术来解决。这个想法是为 K 大小的子数组窗口维护按位与和按位或的值,这可以通过维护一个数组来完成,该数组存储当前窗口所有元素的每个位的计数。如果第i计数 位是K ,该位必须包含在按位与中,如果位的计数大于1 ,则必须包含在按位或中。将其乘积在所有窗口中的最大值存储在变量ans中,这是所需的答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to convert bit array to
// decimal number representing OR
int build_or(int bit[])
{
    int ans = 0;
 
    for (int i = 0; i < 32; i++)
        if (bit[i])
            ans += (1 << i);
 
    return ans;
}
 
// Function to convert bit array to
// decimal number representing AND
int build_and(int bit[], int k)
{
    int ans = 0;
 
    for (int i = 0; i < 32; i++)
        if (bit[i] == k)
            ans += (1 << i);
 
    return ans;
}
 
// Function to find maximum value of
// AND * OR over all K sized subarrays
int maximizeAndOr(int arr[], int N, int K)
{
    // Maintain an integer array bit[]
    // of size 32 all initialized to 0
    int bit[32] = { 0 };
 
    // Create a sliding window of size k
    for (int i = 0; i < K; i++) {
        for (int j = 0; j < 32; j++) {
            if (arr[i] & (1 << j))
                bit[j]++;
        }
    }
 
    int ans = build_and(bit, K) * build_or(bit);
 
    for (int i = K; i < N; i++) {
 
        // Perform operation for
        // removed element
        for (int j = 0; j < 32; j++) {
            if (arr[i - K] & (1 << j))
                bit[j]--;
        }
 
        // Perform operation for
        // added_element
        for (int j = 0; j < 32; j++) {
            if (arr[i] & (1 << j))
                bit[j]++;
        }
 
        // Taking maximum value
        ans = max(ans, build_and(bit, K)
                  * build_or(bit));
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 6, 7, 7, 10, 8, 2 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 3;
 
    cout << maximizeAndOr(arr, N, K);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to convert bit array to
// decimal number representing OR
static int build_or(int[] bit)
{
    int ans = 0;
 
    for(int i = 0; i < 32; i++)
        if (bit[i] > 0)
            ans += (1 << i);
             
    return ans;
}
 
// Function to convert bit array to
// decimal number representing AND
static int build_and(int[] bit, int k)
{
    int ans = 0;
 
    for(int i = 0; i < 32; i++)
        if (bit[i] == k)
            ans += (1 << i);
 
    return ans;
}
 
// Function to find maximum value of
// AND * OR over all K sized subarrays
static int maximizeAndOr(int[] arr, int N, int K)
{
     
    // Maintain an integer array bit[]
    // of size 32 all initialized to 0
    int[] bit = new int[32];
 
    // Create a sliding window of size k
    for(int i = 0; i < K; i++)
    {
        for(int j = 0; j < 32; j++)
        {
            if ((arr[i] & (1 << j)) > 0)
                bit[j]++;
        }
    }
 
    int ans = build_and(bit, K) * build_or(bit);
 
    for(int i = K; i < N; i++)
    {
         
        // Perform operation for
        // removed element
        for(int j = 0; j < 32; j++)
        {
            if ((arr[i - K] & (1 << j)) > 0)
                bit[j]--;
        }
 
        // Perform operation for
        // added_element
        for(int j = 0; j < 32; j++)
        {
            if ((arr[i] & (1 << j)) > 0)
                bit[j]++;
        }
 
        // Taking maximum value
        ans = Math.max(ans, build_and(bit, K) *
                            build_or(bit));
    }
    return ans;
}
 
// Driver Code
public static void main(String args[])
{
    int[] arr = { 6, 7, 7, 10, 8, 2 };
    int N = arr.length;
    int K = 3;
 
    System.out.println(maximizeAndOr(arr, N, K));
}
}
 
// This code is contributed by Samim Hossain Mondal.


Python3
# Python3 program for the above approach
 
# Function to convert bit array to
# decimal number representing OR
def build_or(bit):
     
    ans = 0
 
    for i in range(0, 32):
        if (bit[i]):
            ans += (1 << i)
 
    return ans
 
# Function to convert bit array to
# decimal number representing AND
def build_and(bit, k):
 
    ans = 0
 
    for i in range(0, 32):
        if (bit[i] == k):
            ans += (1 << i)
 
    return ans
 
# Function to find maximum value of
# AND * OR over all K sized subarrays
def maximizeAndOr(arr, N, K):
 
    # Maintain an integer array bit[]
    # of size 32 all initialized to 0
    bit = [0 for _ in range(32)]
 
    # Create a sliding window of size k
    for i in range(0, K):
        for j in range(0, 32):
            if (arr[i] & (1 << j)):
                bit[j] += 1
 
    ans = build_and(bit, K) * build_or(bit)
 
    for i in range(K, N):
 
        # Perform operation for
        # removed element
        for j in range(0, 32):
            if (arr[i - K] & (1 << j)):
                bit[j] -= 1
 
        # Perform operation for
        # added_element
        for j in range(0, 32):
            if (arr[i] & (1 << j)):
                bit[j] += 1
 
        # Taking maximum value
        ans = max(ans, build_and(bit, K) *
                       build_or(bit))
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    arr = [ 6, 7, 7, 10, 8, 2 ]
    N = len(arr)
    K = 3
 
    print(maximizeAndOr(arr, N, K))
 
# This code is contributed by rakeshsahni


C#
// C# program for the above approach
using System;
class GFG
{
   
    // Function to convert bit array to
    // decimal number representing OR
    static int build_or(int[] bit)
    {
        int ans = 0;
 
        for (int i = 0; i < 32; i++)
            if (bit[i] > 0)
                ans += (1 << i);
 
        return ans;
    }
 
    // Function to convert bit array to
    // decimal number representing AND
    static int build_and(int[] bit, int k)
    {
        int ans = 0;
 
        for (int i = 0; i < 32; i++)
            if (bit[i] == k)
                ans += (1 << i);
 
        return ans;
    }
 
    // Function to find maximum value of
    // AND * OR over all K sized subarrays
    static int maximizeAndOr(int[] arr, int N, int K)
    {
        // Maintain an integer array bit[]
        // of size 32 all initialized to 0
        int[] bit = new int[32];
 
        // Create a sliding window of size k
        for (int i = 0; i < K; i++) {
            for (int j = 0; j < 32; j++) {
                if ((arr[i] & (1 << j)) > 0)
                    bit[j]++;
            }
        }
 
        int ans = build_and(bit, K) * build_or(bit);
 
        for (int i = K; i < N; i++) {
 
            // Perform operation for
            // removed element
            for (int j = 0; j < 32; j++) {
                if ((arr[i - K] & (1 << j)) > 0)
                    bit[j]--;
            }
 
            // Perform operation for
            // added_element
            for (int j = 0; j < 32; j++) {
                if ((arr[i] & (1 << j)) > 0)
                    bit[j]++;
            }
 
            // Taking maximum value
            ans = Math.Max(ans, build_and(bit, K)
                                    * build_or(bit));
        }
 
        return ans;
    }
 
    // Driver Code
    public static void Main()
    {
        int[] arr = { 6, 7, 7, 10, 8, 2 };
        int N = arr.Length;
        int K = 3;
 
        Console.WriteLine(maximizeAndOr(arr, N, K));
    }
}
 
// This code is contributed by ukasp.


Javascript


输出
42

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