2044-count-number-of-maximum-bitwise-or-subsets¶
Try it on leetcode
Description¶
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).
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
Solution(Python)¶
class Solution:
def countMaxOrSubsets(self, nums: List[int]) -> int:
return self.memoisation(nums)
# Time Complexity: O(2^n)
# Space Complexity: O(n)
def recursion(self, nums: List[int]) -> int:
max_or_value = 0
for num in nums:
max_or_value |= num
return self._count_recursion(nums, 0, 0, max_or_value)
def _count_recursion(
self, nums: List[int], index: int, current_or: int, target_or: int
) -> int:
# Base case: reached the end of the array
if index == len(nums):
return 1 if current_or == target_or else 0
# Don't include the current number
count_without = self._count_recursion(
nums, index + 1, current_or, target_or
)
# Include the current number
count_with = self._count_recursion(
nums, index + 1, current_or | nums[index], target_or
)
# Return the sum of both cases
return count_without + count_with
# Time Complexity: O(m*M)
# Space Complexity: O(n*M)
def memoisation(self, nums: List[int]) -> int:
max_or_value = 0
for num in nums:
max_or_value |= num
memo = [[-1]*(max_or_value+1) for _ in range(len(nums))]
return self._count_memoisation(nums, 0, 0, max_or_value, memo)
def _count_memoisation(
self, nums: List[int], index: int, current_or: int, target_or: int, memo: List[List[int]],
) -> int:
# Base case: reached the end of the array
if index == len(nums):
return 1 if current_or == target_or else 0
if memo[index][current_or] != -1:
return memo[index][current_or]
# Don't include the current number
count_without = self._count_memoisation(
nums, index + 1, current_or, target_or, memo
)
# Include the current number
count_with = self._count_memoisation(
nums, index + 1, current_or | nums[index], target_or, memo
)
# Return the sum of both cases
memo[index][current_or] = count_without + count_with
return memo[index][current_or]
def bitmask(self, nums: List[int]) -> int:
# Calculate the maximum possible OR value
max_or_value = 0
for num in nums:
max_or_value |= num
total_subsets = 1 << len(nums) # 2^n subsets
subsets_with_max_or = 0
# Iterate through all possible subsets
for subset_mask in range(total_subsets):
current_or_value = 0
# Calculate OR value for the current subset
for i in range(len(nums)):
if (subset_mask >> i) & 1:
current_or_value |= nums[i]
# If current subset's OR equals max_or_value, increment count
if current_or_value == max_or_value:
subsets_with_max_or += 1
return subsets_with_max_or