Count Number of Maximum Bitwise-OR Subsets

Updated on 20 May, 2025
Count Number of Maximum Bitwise-OR Subsets header image

Problem Statement

The task is to find the maximum bitwise OR among all possible subsets of a given integer array nums. Once identified, determine the count of distinct non-empty subsets that yield this maximum bitwise OR.

A subset of an array can be formed by excluding some elements from the array, potentially none. Each subset is unique based on the indices of the elements included. The bitwise OR operation, when applied to an array, is performed progressively from the first element to the last. The challenge lies in analyzing all subsets since their number increases exponentially with the size of the array. This necessitates efficient computational strategies, especially since the array can have up to 16 elements due to given constraints.

Examples

Example 1

Input:

nums = [3,1]

Output:

2

Explanation:

The maximum possible bitwise OR of a subset is 3. There are 2 subsets with a bitwise OR of 3:
- [3]
- [3,1]

Example 2

Input:

nums = [2,2,2]

Output:

7

Explanation:

All non-empty subsets of [2,2,2] have a bitwise OR of 2. There are 23 - 1 = 7 total subsets.

Example 3

Input:

nums = [3,2,1,5]

Output:

6

Explanation:

The maximum possible bitwise OR of a subset is 7. There are 6 subsets with a bitwise OR of 7:
- [3,5]
- [3,1,5]
- [3,2,5]
- [3,2,1,5]
- [2,5]
- [2,1,5]

Constraints

  • 1 <= nums.length <= 16
  • 1 <= nums[i] <= 105

Approach and Intuition

The given problem can be dissected into the following steps:

  1. Identify the Maximum Bitwise OR among Subsets:

    • Initially, it might seem necessary to evaluate the bitwise OR for every subset, but this can be optimized. We can observe that the bitwise OR maximum could only increase or stay the same as more numbers are added to a subset.
    • To find the maximum bitwise OR value, we can compute the OR of all elements in the array as an upper bound.
  2. Count the Subsets Yielding the Maximum Bitwise OR:

    • Start by using a recursive function or an iterative approach to generate subsets.
    • For each subset, compute the bitwise OR and compare it with the maximum value identified. If they match, increment the count.
    • It's important to consider that the subset creation is the combinatorially intensive part of this task, mandating efficient handling or pruning.

The included examples provide clarification:

  • For nums = [3,1], the maximum bitwise OR is obtained either by the subset [3] or [3,1], each yielding an OR of 3.
  • In a scenario where nums = [2,2,2], all non-empty subsets result in the same OR of 2. Therefore, calculating the total non-empty subsets (which is 2^n - 1 for n elements) directly gives us the answer.
  • In a more mixed set like nums = [3,2,1,5], the unique combinations producing the maximum OR of 7 have to be precisely determined.

This approach leverages efficient subset generation and bitwise operations to resolve the challenges posed by potentially large input sizes constrained by the problem's limits.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int countOrSubsetsWithMax(vector<int>& elements) {
        int maxOr = 0;
        vector<int> dpSubset(1 << 17, 0);
        
        // Set base condition for the OR operation
        dpSubset[0] = 1;

        // Process each element to form new subsets
        for (int elem : elements) {
            for (int j = maxOr; j >= 0; j--) {
                // Update counts for subsets after including the new element
                dpSubset[j | elem] += dpSubset[j];
            }
            // Calculate maximum OR across all subsets
            maxOr |= elem;
        }

        return dpSubset[maxOr];
    }
};

The provided C++ code defines a solution to determine the number of subsets within a given set of integers that yield the maximum value when their elements are combined using the bitwise OR operation. The solution employs a dynamic programming approach. Below is an explanation of how the solution operates:

  • Initialize maxOr to zero, to keep track of the maximum bitwise OR value as more elements are processed.
  • A dpSubset vector, initialized with a size large enough to handle all potential bitwise OR results up to 1 << 17, tracks the count of subsets that result in a particular bitwise OR value, starting initially with dpSubset[0] = 1.

The algorithm iterates through each integer in the input vector elements:

  1. For each element elem:
    • Iterate backward through dpSubset from maxOr to 0. This loop updates dpSubset[j | elem] by adding the count from dpSubset[j]. This step updates all achievable OR values after adding the new element to previously considered subsets.
    • Update maxOr by OR-ing it with elem to ensure it holds the maximum OR value possible with the current subset of integers.

After processing all elements, dpSubset[maxOr] contains the count of subsets whose bitwise OR results in the maximum value, which is then returned by the function countOrSubsetsWithMax. This approach avoids direct subset generation and provides a more efficient way to count subsets by leveraging bitwise operations and dynamic programming techniques.

java
class Solution {

    public int maxOrSubsetsCount(int[] arr) {
        int maxOr = 0;
        int[] subsetsCount = new int[1 << 17];

        // Initialize count for empty subset
        subsetsCount[0] = 1;

        // Process each number in the array
        for (int value : arr) {
            for (int j = maxOr; j >= 0; j--) {
                // Update the subsets count including the new number
                subsetsCount[j | value] += subsetsCount[j];
            }
            // Update the maximum OR value computed so far
            maxOr |= value;
        }

        return subsetsCount[maxOr];
    }
}

This Java program solves the problem of counting the number of subsets that have the maximum bitwise OR value from a given array arr. The primary approach uses dynamic programming to efficiently calculate the desired count without generating each subset explicitly.

  • Initialize an array subsetsCount to keep track of the count of subsets for each possible OR value. The size of this array is set large enough to accommodate all possible outcomes (up to 1 << 17).

  • Set the count for the empty subset (subsetsCount[0]) to 1 since every non-empty set includes the empty set as a subset.

  • Iterate over each element in the input array. For each element:

    • Iterate backward from the current maximum OR value (maxOr) to 0. This reverse iteration ensures that modifications to subsetsCount do not affect subsequent calculations in the same loop.
    • For each value j in this iteration, update subsetsCount[j | value] by adding the count of existing subsets represented by j. This update reflects forming new subsets by adding the current element to existing subsets.
  • After processing each array element, update maxOr to incorporate the current element using the OR operation (maxOr |= value). This variable keeps track of the maximum OR value obtained from any subset of the array.

  • Finally, the function returns the count of subsets that have achieved this maximum OR value, accessed via subsetsCount[maxOr].

This program effectively leverages bitwise operations and dynamic programming principles, ensuring that the solution remains efficient, even for larger input sizes.

python
class Solution:
    def maximumOrSubsets(self, elements: List[int]) -> int:
        highest_or = 0
        count = [0] * (1 << 17)

        # Starting with the empty subset
        count[0] = 1

        # Loop through every element in the list
        for element in elements:
            for j in range(highest_or, -1, -1):
                # Extend existing subsets with current element
                count[j | element] += count[j]

            # Refresh the highest OR value obtained so far
            highest_or |= element

        return count[highest_or]

The provided Python function maximumOrSubsets efficiently counts how many subsets of an array have a bitwise OR that equals the maximum possible bitwise OR of any subset of the array.

Understanding the approach is key:

  • Initialize the highest OR value as 0. This represents the largest OR value computed from any subset so far.
  • Use a list count to maintain counts of subsets for each possible OR value up to 2^17-1 (reflecting the OR computation limits due to the maximum constraints typically allowed in similar problems).

Steps to achieve the solution:

  1. For each element in the input list elements, iterate over possible OR values (from highest_or down to 0).
  2. For each value j in this range, update the count for j | element. This entails adding the number of subsets that can be formed by including the current element which contributes to the new OR value j | element.
  3. Update highest_or after including each element, guaranteeing it stores the maximum OR value found so far.

Finally, by the end of the loop, highest_or will hold the maximum OR value that can be achieved by any subset, and count[highest_or] will hold the number of subsets that achieve this OR value.

This method is optimized and avoids computing all possible subsets explicitly, focusing instead on incrementally building up by each element and only keeping track of the counts of subsets that achieve each possible OR value.

Comments

No comments yet.