💡 Multiple subsets can share the maximum OR value.
reconstruct
Return final count
All subsets processed; return count which is 2, the number of subsets with max OR.
💡 The final count is the answer to the problem.
Line:return count
💡 The algorithm correctly counted subsets with maximum bitwise OR.
from typing import List
class Solution:
def countMaxOrSubsets(self, nums: List[int]) -> int:
n = len(nums) # STEP 1
max_or = 0 # STEP 1
count = 0 # STEP 1
for mask in range(1, 1 << n): # STEP 2,6,10
current_or = 0 # STEP 2,6,10
for i in range(n): # STEP 3,4,7,8,11,12
if mask & (1 << i): # STEP 3,4,7,8,11,12
current_or |= nums[i] # STEP 3,8,11,12
if current_or > max_or: # STEP 5,13
max_or = current_or # STEP 5
count = 1 # STEP 5
elif current_or == max_or: # STEP 13
count += 1 # STEP 13
return count # STEP 14
if __name__ == '__main__':
sol = Solution()
print(sol.countMaxOrSubsets([3,1])) # Expected output: 2
print(sol.countMaxOrSubsets([2,2,2])) # Expected output: 7
📊
Count Number of Max Bitwise-OR Subsets - Watch the Algorithm Execute, Step by Step
Watching each subset being generated and evaluated helps you understand how bitmask enumeration works and why the algorithm correctly counts subsets with the maximum bitwise OR.
Step 1/14
·Active fill★Answer cell
enteringnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Remaining
mask=1 to 3
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1
Remaining
mask=2mask=3
Partial: [mask=1]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1, i=0 included
Remaining
mask=1, i=1 excluded
Partial: [mask=1, included nums[0]=3]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1, i=0 includedmask=1, i=1 excluded
Partial: [mask=1, included nums[0]=3]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1 processed
Remaining
mask=2mask=3
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1mask=2
Remaining
mask=3
Partial: [mask=2]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=2, i=0 excluded
Remaining
mask=2, i=1 included
Partial: [mask=2]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=2, i=0 excludedmask=2, i=1 included
Partial: [mask=2, included nums[1]=1]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1mask=2
Remaining
mask=3
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1mask=2mask=3
Partial: [mask=3]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=3, i=0 included
Remaining
mask=3, i=1 included
Partial: [mask=3, included nums[0]=3]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=3, i=0 includedmask=3, i=1 included
Partial: [mask=3, included nums[0]=3, included nums[1]=1]
choosingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1mask=2mask=3
backtrackingnums=[3,1]
Call Path (current → root)
countMaxOrSubsets([3,1])
Tried
mask=1mask=2mask=3
Found 1: [2]
Key Takeaways
✓ Enumerating subsets with bitmasks allows systematic and complete exploration of all subsets.
This is hard to see from code alone because the bitmask iteration looks like a loop, but visualizing each mask as a subset clarifies the process.
✓ The bitwise OR operation accumulates values from included elements, revealing how subsets combine bits.
Seeing the OR build step-by-step helps understand why the OR of a subset is computed by OR-ing included elements.
✓ Tracking max_or and count separately shows how the algorithm updates the best OR and counts subsets achieving it.
The decision to reset count or increment it is clearer when watching each subset's OR compared to max_or.
Practice
(1/5)
1. You are given a set of distinct positive integers and a target sum. You need to find all unique combinations where the chosen numbers sum to the target. Each number can be chosen multiple times. Which algorithmic approach best guarantees finding all valid combinations efficiently without missing any or producing duplicates?
easy
A. Greedy algorithm that picks the largest candidate repeatedly until the sum is reached or exceeded.
B. Backtracking with sorting and frequency counting to avoid duplicates and prune early when sum exceeds target.
C. Dynamic programming using a 2D table to count the number of combinations without generating them explicitly.
D. Pure brute force recursion that tries all subsets without pruning or sorting.
Solution
Step 1: Understand problem constraints
The problem requires all unique combinations summing to target, allowing reuse of candidates.
Step 2: Evaluate algorithm suitability
Greedy fails because it can miss combinations; pure brute force is correct but inefficient; DP counts combinations but doesn't generate them; backtracking with sorting and frequency counting avoids duplicates and prunes search space efficiently.
Final Answer:
Option B -> Option B
Quick Check:
Backtracking with pruning and frequency counting is the standard approach [OK]
Hint: Backtracking with pruning avoids duplicates and excessive search [OK]
Common Mistakes:
Assuming greedy always works for sum problems
Confusing counting with generating combinations
2. Consider the following Python function that counts subsets with sum K using a space-optimized DP approach. What is the output when called with arr = [1, 2, 3, 3] and K = 6?
def count_subsets_space_optimized(arr, K):
dp = [0] * (K + 1)
dp[0] = 1
for num in arr:
for j in range(K, num - 1, -1):
dp[j] += dp[j - num]
return dp[K]
print(count_subsets_space_optimized(arr, K))
easy
A. 5
B. 4
C. 3
D. 6
Solution
Step 1: Initialize dp array
dp = [1,0,0,0,0,0,0] since dp[0]=1 and K=6.
Step 2: Process each number updating dp
After processing 1: dp = [1,1,0,0,0,0,0]
After 2: dp = [1,1,1,1,0,0,0]
After first 3: dp = [1,1,1,2,1,1,1]
After second 3: dp = [1,1,1,3,2,2,3]
Final Answer:
Option A -> Option A
Quick Check:
dp[6] = 5 subsets sum to 6 [OK]
Hint: Trace dp updates backward to avoid double counting [OK]
Common Mistakes:
Forgetting to iterate backward in dp array
Off-by-one errors in dp indices
3. Consider the following Python code implementing the optimal backtracking with bitmask and memoization approach for the Matchsticks to Square problem. Given the input [1,1,2,2,2], what is the final return value of makesquare([1,1,2,2,2])?
easy
A. True
B. Depends on the order of matchsticks
C. Raises an exception due to index error
D. False
Solution
Step 1: Calculate total and side length
Total = 1+1+2+2+2 = 8, side = 8/4 = 2.
Step 2: Trace backtracking calls
Sorted sticks: [2,2,2,1,1]. The algorithm tries to form sides of length 2. It can form three sides with three 2's, and the last side with two 1's. Hence, returns true.
Final Answer:
Option A -> Option A
Quick Check:
Sum divisible by 4 and sticks fit sides exactly [OK]
Hint: Sum divisible by 4 and sticks fit sides exactly [OK]
Common Mistakes:
Forgetting to sort and prune
Assuming order affects result
Miscounting sides formed
4. The following code attempts to solve Combination Sum (Reuse Allowed). Identify the line containing the subtle bug that causes incorrect results or inefficiency:
def combinationSum(candidates, target):
candidates.sort()
result = []
def backtrack(index, path, target):
if target == 0:
result.append(path[:])
return
if index == len(candidates) or target < 0:
return
max_use = target // candidates[index]
for count in range(max_use + 1):
path += [candidates[index]] * count
backtrack(index + 1, path, target - candidates[index] * count)
# Missing path restoration here
backtrack(0, [], target)
return result
medium
A. Line with 'path += [candidates[index]] * count' because path is modified without backtracking (pop).
B. Line with 'candidates.sort()' because sorting is unnecessary.
C. Line with 'if target == 0:' because it should check for target <= 0.
D. Line with 'max_use = target // candidates[index]' because integer division may cause errors.
Solution
Step 1: Analyze path modification in loop
Path is extended by count copies of candidates[index] but never restored after recursive call, causing path to grow incorrectly across iterations.
Step 2: Identify missing backtracking step
Proper backtracking requires removing added elements after recursion to restore path state for next iteration.
Final Answer:
Option A -> Option A
Quick Check:
Modifying path without restoration leads to incorrect combinations [OK]
Hint: Always restore path after recursion in backtracking [OK]
Common Mistakes:
Forgetting to pop elements after recursion
Assuming path copy avoids mutation issues
5. What is the time complexity of generating all subsets of an array of size n using bitmask enumeration, and why is the common misconception that it is O(2^n) incorrect?
medium
A. O(n^2) because we iterate over n elements twice
B. O(2^n) because there are 2^n subsets
C. O(n * 2^n) because each subset can have up to n elements and we build each subset by checking n bits
D. O(n) because we process each element once
Solution
Step 1: Count subsets and subset size
There are 2^n subsets, and each subset can have up to n elements.
Step 2: Analyze bitmask enumeration cost
For each of the 2^n masks, we check n bits to build the subset, resulting in O(n * 2^n) time.
Final Answer:
Option C -> Option C
Quick Check:
Time depends on both number of subsets and subset size [OK]
Hint: Each subset requires O(n) to build, total O(n*2^n) [OK]
Common Mistakes:
Ignoring subset size in complexity
Assuming O(2^n) only
Confusing with DP complexities
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.