Open In App

Smallest subarray such that its bitwise OR is at least k

Last Updated : 12 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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);

Output
Minimum subarray length with sum >= k: 1

Time Complexity: O(32*N)
Auxiliary Space: O(1)



    Like Article
    Suggest improvement
    Previous
    Next
    Share your thoughts in the comments

    Similar Reads