Given an array arr[] of positive integers and an number K, the task is to find the minimum and maximum values of Bitwise operation on elements of subarray of size K.
Examples:
Input:_ arr[]={2, 5, 3, 6, 11, 13}, k = 3_
Output:
Maximum AND = 2
Minimum AND = 0
Maximum OR = 15
Minimum OR = 7
Explanation:
Maximum AND is generated by subarray 3, 6 and 11, 3 & 6 & 11 = 2
Minimum AND is generated by subarray 2, 3 and 5, 2 & 3 & 5 = 0
Maximum OR is generated by subarray 2, 6 and 13, 2 | 6 | 13 = 15
Minimum OR is generated by subarray 2, 3 and 5, 2 | 3 | 5 = 7
Input:_ arr[]={5, 9, 7, 19}, k = 2_
Output:
Maximum AND = 3
Minimum AND = 1
Maximum OR = 23
Minimum OR = 13
Naive Approach: The naive approach is generate all possible subarrays of size K and check which of the above formed subarray will give the minimum and maximum Bitwise OR and AND.
Time Complexity: O(N2)
Auxiliary Space: O(K)
Efficient Approach: The idea is to use Sliding Window Technique to solve this problem. Below are the steps:
Below is the program to find the Maximum Bitwise OR subarray:
// C++ program for maximum values of
// each bitwise OR operation on
// element of subarray of size K
#include <iostream>
**using**
**namespace**
std;
// Function to convert bit array to
// decimal number
**int**
build_num(``**int**
bit[])
{
**int**
ans = 0;
**for**
(``**int**
i = 0; i < 32; i++)
**if**
(bit[i])
ans += (1 << i);
**return**
ans;
}
// Function to find maximum values of
// each bitwise OR operation on
// element of subarray of size K
**int**
maximumOR(``**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]++;
}
}
// Function call
**int**
max_or = build_num(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
max_or = max(build_num(bit), max_or);
}
// Return the result
**return**
max_or;
}
// Driver Code
**int**
main()
{
// Given array arr[]
**int**
arr[] = { 2, 5, 3, 6, 11, 13 };
// Given subarray size K
**int**
k = 3;
**int**
n =
**sizeof**
arr /
**sizeof**
arr[0];
// Function Call
cout << maximumOR(arr, n, k);
**return**
0;
}
Output:
15
Time Complexity: O(n * B) where n is the size of the array and B is the integer array bit of size 32.
Auxiliary Space: O(n)
Below is the program to find the Minimum Bitwise OR subarray:
// C++ program for minimum values of
// each bitwise OR operation on
// element of subarray of size K
#include <iostream>
**using**
**namespace**
std;
// Function to convert bit array
// to decimal number
**int**
build_num(``**int**
bit[])
{
**int**
ans = 0;
**for**
(``**int**
i = 0; i < 32; i++)
**if**
(bit[i])
ans += (1 << i);
**return**
ans;
}
// Function to find minimum values of
// each bitwise OR operation on
// element of subarray of size K
**int**
minimumOR(``**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]++;
}
}
// Function call
**int**
min_or = build_num(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 minimum value
min_or = min(build_num(bit),
min_or);
}
// Return the result
**return**
min_or;
}
// Driver Code
**int**
main()
{
// Given array arr[]
**int**
arr[] = { 2, 5, 3, 6, 11, 13 };
// Given subarray size K
**int**
k = 3;
**int**
n =
**sizeof**
arr /
**sizeof**
arr[0];
// Function Call
cout << minimumOR(arr, n, k);
**return**
0;
}
Output:
7
Time Complexity: O(n * B) where n is the size of the array and B is the integer array bit of size 32.
Auxiliary Space: O(n)
Below is the program to find the Maximum Bitwise AND subarray:
// C++ program for maximum values of
// each bitwise AND operation on
// element of subarray of size K
#include <iostream>
**using**
**namespace**
std;
// Function to convert bit array
// to decimal number
**int**
build_num(``**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 values of
// each bitwise AND operation on
// element of subarray of size K
**int**
maximumAND(``**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]++;
}
}
// Function call
**int**
max_and = build_num(bit, k);
**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
max_and = max(build_num(bit, k),
max_and);
}
// Return the result
**return**
max_and;
}
// Driver Code
**int**
main()
{
// Given array arr[]
**int**
arr[] = { 2, 5, 3, 6, 11, 13 };
// Given subarray size K
**int**
k = 3;
**int**
n =
**sizeof**
arr /
**sizeof**
arr[0];
// Function Call
cout << maximumAND(arr, n, k);
**return**
0;
}
Output:
2
Time Complexity: O(n * B) where n is the size of the array and B is the integer array bit of size 32.
Auxiliary Space: O(n)
Below is the program to find the Minimum Bitwise AND subarray:
// C++ program for minimum values of
// each bitwise AND operation on
// elements of subarray of size K
#include <iostream>
**using**
**namespace**
std;
// Function to convert bit array
// to decimal number
**int**
build_num(``**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 minimum values of
// each bitwise AND operation on
// element of subarray of size K
**int**
minimumAND(``**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]++;
}
}
// Function call
**int**
min_and = build_num(bit, k);
**for**
(``**int**
i = k; i < n; i++) {
// Perform operation to removed
// element
**for**
(``**int**
j = 0; j < 32; j++) {
**if**
(arr[i - k] & (1 << j))
bit[j]--;
}
// Perform operation to add
// element
**for**
(``**int**
j = 0; j < 32; j++) {
**if**
(arr[i] & (1 << j))
bit[j]++;
}
// Taking minimum value
min_and = min(build_num(bit, k),
min_and);
}
// Return the result
**return**
min_and;
}
// Driver Code
**int**
main()
{
// Given array arr[]
**int**
arr[] = { 2, 5, 3, 6, 11, 13 };
// Given subarray size K
**int**
k = 3;
**int**
n =
**sizeof**
arr /
**sizeof**
arr[0];
// Function Call
cout << minimumAND(arr, n, k);
**return**
0;
}
Output:
0
Time Complexity: O(n * B) where n is the size of the array and B is the integer array bit of size 32.
Auxiliary Space: O(n)
Below is the program to find the Minimum Bitwise XOR subarray:
// C++ program to find the subarray
/// with minimum XOR
#include <bits/stdc++.h>
**using**
**namespace**
std;
// Function to find the minimum XOR
// of the subarray of size K
**void**
findMinXORSubarray(``**int**
arr[],
**int**
n,
**int**
k)
{
// K must be smaller than
// or equal to n
**if**
(n < k)
**return**``;
// Initialize the beginning
// index of result
**int**
res_index = 0;
// Compute XOR sum of first
// subarray of size K
**int**
curr_xor = 0;
**for**
(``**int**
i = 0; i < k; i++)
curr_xor ^= arr[i];
// Initialize minimum XOR
// sum as current xor
**int**
min_xor = curr_xor;
// Traverse from (k+1)'th
// element to n'th element
**for**
(``**int**
i = k; i < n; i++) {
// XOR with current item
// and first item of
// previous subarray
curr_xor ^= (arr[i] ^ arr[i - k]);
// Update result if needed
**if**
(curr_xor < min_xor) {
min_xor = curr_xor;
res_index = (i - k + 1);
}
}
// Print the minimum XOR
cout << min_xor <<
"\n"``;
}
// Driver Code
**int**
main()
{
// Given array arr[]
**int**
arr[] = { 3, 7, 90, 20, 10, 50, 40 };
// Given subarray size K
**int**
k = 3;
**int**
n =
**sizeof**``(arr) /
**sizeof**``(arr[0]);
// Function Call
findMinXORSubarray(arr, n, k);
**return**
0;
}
Output:
16
#arrays #bit magic #competitive programming #bitwise-and #bitwise-or #bitwise-xor #subarray