Given an integer array nums, find the maximum possible bitwise OR of a subset of nums and return the number of different non-empty subsets with the maximum bitwise OR.
An array a is a subset of an array b if a can be obtained from b by deleting some (possibly zero) elements of b. Two subsets are considered different if the indices of the elements chosen are different.
The bitwise OR of an array a is equal to a[0] OR a[1] OR ... OR a[a.length - 1] (0-indexed).
Input: nums =[3,1]Output: 2Explanation: The maximum possible bitwise OR of a subset is3. There are 2 subsets with a bitwise OR of 3:-[3]-[3,1]
Example 2:
1
2
3
Input: nums =[2,2,2]Output: 7Explanation: All non-empty subsets of [2,2,2] have a bitwise OR of 2. There are 23-1=7 total subsets.
Example 3:
1
2
3
4
5
6
7
8
9
Input: nums =[3,2,1,5]Output: 6Explanation: The maximum possible bitwise OR of a subset is7. 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]
When we have to compute the maximum bitwise OR of subsets, since OR operations are cumulative (meaning that once a bit is set, it remains set), including more elements in a subset typically brings the result closer to the maximum possible OR value. Therefore, after computing the maximum OR, we can count how many subsets achieve this maximum. So, the problem boils down to:
Compute the Maximum OR by combining all the elements in the array.
Explore Every Subset of the array and count how many subsets yield this maximum OR value.
The key insight here is that the more elements we OR together, the higher the resultant OR value tends to be. This makes backtracking a suitable method to systematically explore each subset, ensuring we account for all possible combinations.
So, here is the approach:
Compute Maximum OR: First, determine the maximum possible OR value by applying the | (bitwise OR) operation to all elements in the array. This value represents the highest OR any subset can achieve.
Backtracking: Then, use backtracking to explore all potential subsets. Calculate the OR value for each subset. If it equals the maximum OR, increment the counter. This is similar to Subsets.
Base Case: When the OR of a subset matches the maximum, count it. Continue recursively exploring all subsets until all options have been examined.
classSolution {
privateint[] nums; // Array to store input numbersprivateint maxOr; // Variable to store the maximum OR valuepublicintcountMaxOrSubsets(int[] nums) {
this.nums= nums;
int maxOr = 0;
// Step 1: Compute the maximum OR by combining all elementsfor (int num : nums) {
maxOr |= num; // Bitwise OR operation with the current number }
this.maxOr= maxOr; // Store the maximum OR value// Step 2: Use DFS to count the subsets that achieve the maximum ORreturn dfs(0, 0); // Start DFS with index 0 and current OR value 0 }
// DFS function to explore all subsetsprivateintdfs(int idx, int currOr) {
// Base case: If we've considered all elementsif (idx == nums.length) {
return currOr == maxOr ? 1 : 0; // Return 1 if current OR equals max OR, otherwise return 0 }
// Consider two cases:// 1. Including nums[idx] in the current subsetint include = dfs(idx + 1, currOr | nums[idx]);
// 2. Excluding nums[idx] from the current subsetint exclude = dfs(idx + 1, currOr);
// Return the sum of both casesreturn include + exclude;
}
}
⏰ Time complexity: O(n.2^n), since the total number of subsets is 2^n, where n is the length of the array. For each subset, we compute the OR, which takes O(n).
🧺 Space complexity: O(n), for using recursion stack.
classSolution:
defcountMaxOrSubsets(self, nums: List[int]) -> int:
self.nums = nums
self.max_or =0# Step 1: Compute the maximum ORfor num in nums:
self.max_or |= num
# Step 2: Use a recursive function with caching to count the subsets@lru_cache(None)
defdfs(idx, current_or):
if idx == len(nums):
return1if current_or == self.max_or else0# Consider two cases: including nums[idx] or excluding nums[idx] include = dfs(idx +1, current_or | nums[idx])
exclude = dfs(idx +1, current_or)
return include + exclude
# Initialize the count with the first index and OR value 0return dfs(0, 0)