Smallest subarray such that its bitwise OR is at least k
Last Updated :
12 May, 2024
Given an array arr[] of non-negative integers and an integer k. The task is to find the smallest non-empty subarray of arr[] such that the bitwise OR of all of its elements is at least k, or return -1 if no subarray exists.
Example:
Input: arr = {1,2,3}, k = 2
Output: 1
Explanation: The subarray {3} has OR value of 3. Hence, we return 1.
Input: arr = {2,1,8}, k = 10
Output: 3
Explanation: The subarray {2,1,8} has OR value of 11. Hence, we return 3.
Input: arr = {1,2}, k = 0
Output: 1
Explanation: The subarray {1} has OR value of 1. Hence, we return 1.
Approach:
We can use sliding window approach to solve this problem. When the running bitwise OR becomes greater than k, we will update our left pointer (shrink the sliding window) until the OR is less than k, and then update our answer accordingly.
The main concept involves calculating the new OR when we shrink the window.
- Initially, we store the count of set bits at any ith position for arr[i].
- When the OR becomes greater than or equal to k, we run a while loop until the OR is less than k.
- Within the while loop, we subtract the set bits in arr[l] from bitsCount and calculate the new OR value from the set bits in bitsCount.
- This can be achieved by either unsetting the jth bit in the OR if bitsCount[j] equals 0, or by using a new variable newcurrent_OR and setting the jth bit if bitsCount[j] is greater than 0.
Step-by-step approach:
- Initialize:
- Set ans to the maximum possible length (array size + 1).
- Set current_OR to 0.
- Create a bitCount vector to store bit counts (size 32).
- Set left to 0.
- Iterate through the array:
- Update current_OR with the current element’s OR value.
- Update bitCount for the current element’s bits.
- Shrink the window:
- While current_OR is greater than or equal to k:
- Update ans with the minimum length if needed.
- Calculate a new current_OR and update bitCount for the shrunk window.
- Move left one position to the right.
- If ans is still the maximum possible length, return -1 (no subarray found).
- Otherwise, return ans (minimum length).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minimumSubarrayLength(vector<int>& nums, int k)
{
// Initialize the answer to the maximum possible value
// (length of the array + 1)
int ans = nums.size() + 1;
// Initialize the current OR value to 0
int current_OR = 0;
// Create a vector to store the count of set bits at
// each position in the window
vector<int> bitCount(32, 0);
// Initialize the left pointer to the beginning of the
// window
int left = 0;
for (int i = 0; i < nums.size(); i++) {
// Update the current OR value with the current
// element
current_OR |= nums[i];
// Set the bits in bitCount for nums[i]
for (int j = 31; j >= 0; j--) {
// Check if the j-th bit is set in nums[i] and
// increment the count
bitCount[j] += (nums[i] & (1 << j)) > 0;
}
// If the current OR value is greater than or equal
// to k, shrink the window from the left
while (left <= i && current_OR >= k) {
if (current_OR >= k) {
// Update the answer with the minimum length
// of the subarray
ans = min(ans, i - left + 1);
}
// Initialize the new OR value for the shrunk
// window
int new_or = 0;
// Calculate the new OR value and update
// bitCount
for (int j = 31; j >= 0; j--) {
// Check if the j-th bit is set in
// nums[left]
int bit = nums[left] & (1 << j);
// Decrement the count of the j-th bit if it
// was set in nums[left]
bitCount[j] -= bit > 0;
if (bitCount[j] > 0) {
// Set the j-th bit in new_or if the
// count is still greater than 0
new_or |= (1 << j);
}
}
// Update the current OR value with the new OR
// value
current_OR = new_or;
// Move the left pointer one position to the
// right
left++;
}
}
// Return -1 if no subarray with the required sum
// exists, otherwise return the minimum length
return ans == nums.size() + 1 ? -1 : ans;
}
int main()
{
vector<int> arr = { 1, 2, 3 };
int k = 2;
int minLength = minimumSubarrayLength(arr, k);
cout << "Minimum subarray length with sum >= k: "
<< minLength << endl;
return 0;
}
Java
import java.util.Arrays;
public class MinimumSubarrayLength {
public static int minimumSubarrayLength(int[] nums,
int k)
{
// Initialize the answer to the maximum possible
// value (length of the array + 1)
int ans = nums.length + 1;
// Initialize the current OR value to 0
int current_OR = 0;
// Create an array to store the count of set bits at
// each position in the window
int[] bitCount = new int[32];
// Initialize the left pointer to the beginning of
// the window
int left = 0;
for (int i = 0; i < nums.length; i++) {
// Update the current OR value with the current
// element
current_OR |= nums[i];
// Set the bits in bitCount for nums[i]
for (int j = 31; j >= 0; j--) {
// Check if the j-th bit is set in nums[i]
// and increment the count
bitCount[j]
+= (nums[i] & (1 << j)) > 0 ? 1 : 0;
}
// If the current OR value is greater than or
// equal to k, shrink the window from the left
while (left <= i && current_OR >= k) {
if (current_OR >= k) {
// Update the answer with the minimum
// length of the subarray
ans = Math.min(ans, i - left + 1);
}
// Initialize the new OR value for the
// shrunk window
int new_or = 0;
// Calculate the new OR value and update
// bitCount
for (int j = 31; j >= 0; j--) {
// Check if the j-th bit is set in
// nums[left]
int bit = nums[left] & (1 << j);
// Decrement the count of the j-th bit
// if it was set in nums[left]
bitCount[j] -= bit > 0 ? 1 : 0;
if (bitCount[j] > 0) {
// Set the j-th bit in new_or if the
// count is still greater than 0
new_or |= (1 << j);
}
}
// Update the current OR value with the new
// OR value
current_OR = new_or;
// Move the left pointer one position to the
// right
left++;
}
}
// Return -1 if no subarray with the required sum
// exists, otherwise return the minimum length
return ans == nums.length + 1 ? -1 : ans;
}
public static void main(String[] args)
{
int[] arr = { 1, 2, 3 };
int k = 2;
int minLength = minimumSubarrayLength(arr, k);
System.out.println(
"Minimum subarray length with sum >= k: "
+ minLength);
}
}
// This code is contributed by shivamgupta0987654321
Python
def minimumSubarrayLength(nums, k):
# Initialize the answer to the maximum possible
# value (length of the array + 1)
ans = len(nums) + 1
# Initialize the current OR value to 0
current_OR = 0
# Create a list to store the count of set bits at
# each position in the window
bitCount = [0] * 32
# Initialize the left pointer to the beginning of
# the window
left = 0
for i in range(len(nums)):
# Update the current OR value with the current
# element
current_OR |= nums[i]
# Set the bits in bitCount for nums[i]
for j in range(31, -1, -1):
# Check if the j-th bit is set in nums[i]
# and increment the count
if nums[i] & (1 << j):
bitCount[j] += 1
# If the current OR value is greater than or
# equal to k, shrink the window from the left
while left <= i and current_OR >= k:
if current_OR >= k:
# Update the answer with the minimum
# length of the subarray
ans = min(ans, i - left + 1)
# Initialize the new OR value for the
# shrunk window
new_or = 0
# Calculate the new OR value and update
# bitCount
for j in range(31, -1, -1):
# Check if the j-th bit is set in
# nums[left]
bit = nums[left] & (1 << j)
# Decrement the count of the j-th bit
# if it was set in nums[left]
bitCount[j] -= 1 if bit else 0
if bitCount[j] > 0:
# Set the j-th bit in new_or if the
# count is still greater than 0
new_or |= (1 << j)
# Update the current OR value with the new
# OR value
current_OR = new_or
# Move the left pointer one position to the
# right
left += 1
# Return -1 if no subarray with the required sum
# exists, otherwise return the minimum length
return ans if ans != len(nums) + 1 else -1
# Sample Input
arr = [1, 2, 3]
k = 2
minLength = minimumSubarrayLength(arr, k)
print("Minimum subarray length with sum >= k:", minLength)
JavaScript
function minimumSubarrayLength(nums, k) {
// Initialize the answer to the maximum possible
// value (length of the array + 1)
let ans = nums.length + 1;
// Initialize the current OR value to 0
let current_OR = 0;
// Create an array to store the count of set bits at
// each position in the window
let bitCount = new Array(32).fill(0);
// Initialize the left pointer to the beginning of
// the window
let left = 0;
for (let i = 0; i < nums.length; i++) {
// Update the current OR value with the current
// element
current_OR |= nums[i];
// Set the bits in bitCount for nums[i]
for (let j = 31; j >= 0; j--) {
// Check if the j-th bit is set in nums[i]
// and increment the count
bitCount[j] += (nums[i] & (1 << j)) > 0 ? 1 : 0;
}
// If the current OR value is greater than or
// equal to k, shrink the window from the left
while (left <= i && current_OR >= k) {
if (current_OR >= k) {
// Update the answer with the minimum
// length of the subarray
ans = Math.min(ans, i - left + 1);
}
// Initialize the new OR value for the
// shrunk window
let new_or = 0;
// Calculate the new OR value and update
// bitCount
for (let j = 31; j >= 0; j--) {
// Check if the j-th bit is set in
// nums[left]
let bit = nums[left] & (1 << j);
// Decrement the count of the j-th bit
// if it was set in nums[left]
bitCount[j] -= bit > 0 ? 1 : 0;
if (bitCount[j] > 0) {
// Set the j-th bit in new_or if the
// count is still greater than 0
new_or |= 1 << j;
}
}
// Update the current OR value with the new
// OR value
current_OR = new_or;
// Move the left pointer one position to the
// right
left++;
}
}
// Return -1 if no subarray with the required sum
// exists, otherwise return the minimum length
return ans === nums.length + 1 ? -1 : ans;
}
let arr = [1, 2, 3];
let k = 2;
let minLength = minimumSubarrayLength(arr, k);
console.log("Minimum subarray length with sum >= k: " + minLength);
OutputMinimum subarray length with sum >= k: 1
Time Complexity: O(32*N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...