2275. Largest Combination With Bitwise AND Greater Than Zero
Problem Description
You are given an array of positive integers called candidates
. Your task is to find the size of the largest possible combination of elements from this array such that their bitwise AND is greater than 0.
The bitwise AND operation takes multiple numbers and performs an AND operation on each bit position across all numbers. For a combination to have a bitwise AND greater than 0, at least one bit position must have a 1 in all selected numbers.
For example:
- If
candidates = [1, 5, 3]
, the bitwise AND would be1 & 5 & 3 = 1
(in binary:001 & 101 & 011 = 001
) - If
candidates = [7]
, the bitwise AND is simply7
The key insight is that for the bitwise AND of a combination to be greater than 0, there must be at least one bit position where all numbers in that combination have a 1. The solution counts how many numbers have a 1 at each bit position and returns the maximum count across all bit positions.
The approach iterates through each bit position (from 0 to the bit length of the maximum number) and counts how many numbers have a 1 at that position using x >> i & 1
. This gives us the maximum possible combination size where all numbers share at least one common bit set to 1.
Intuition
To understand why this solution works, let's think about what makes a bitwise AND result greater than 0. When we perform AND operation on multiple numbers, the result is 0 only when there's no bit position where all numbers have a 1. Conversely, for the AND to be greater than 0, there must exist at least one bit position where every number in our combination has a 1.
Consider this: if we want the largest combination with AND > 0, we need to find the bit position that has the most 1s across all candidates. Why? Because at any given bit position, we can only include numbers that have a 1 at that position in our combination. If a number has a 0 at that bit position, including it would make that bit 0 in the final AND result.
For example, if we're looking at bit position 2 and we have numbers [5, 6, 7, 4]
(in binary: [101, 110, 111, 100]
), only numbers 5, 6, and 7 have a 1 at position 2. So the maximum combination for this bit position is 3.
The brilliant insight is that we don't need to generate all possible combinations and check their AND results. Instead, we can independently check each bit position and count how many numbers could potentially be in a combination for that bit. The maximum count across all bit positions gives us our answer.
This works because having multiple 1s at different bit positions doesn't help us include more numbers - we're constrained by the bit position with the fewest 1s among our chosen numbers. So we optimize by finding the single bit position that allows us to include the most numbers.
Solution Approach
The implementation uses bit manipulation to efficiently solve this problem. Here's how the solution works step by step:
-
Find the maximum bit length: First, we need to determine how many bit positions to check. We use
max(candidates).bit_length()
to find the number of bits needed to represent the largest number in the array. This ensures we check all relevant bit positions. -
Iterate through each bit position: We loop through each bit position from 0 to the maximum bit length. For each position
i
, we want to count how many numbers have a 1 at that position. -
Count 1s at each bit position: For each bit position
i
, we use the expressionx >> i & 1
for every numberx
in candidates:x >> i
shifts the number right byi
positions, bringing the bit at positioni
to the least significant position& 1
masks everything except the least significant bit, giving us either 0 or 1sum(x >> i & 1 for x in candidates)
counts the total number of 1s at positioni
across all candidates
-
Track the maximum count: We maintain
ans
to store the maximum count found so far. After checking each bit position, we updateans
usingmax(ans, current_count)
. -
Return the result: The final value of
ans
represents the size of the largest combination where all numbers share at least one common bit set to 1.
For example, if candidates = [16, 17, 71, 62, 12, 24, 14]
:
- Bit position 0: numbers with 1 at this position: [17, 71] → count = 2
- Bit position 1: numbers with 1 at this position: [71, 62, 14] → count = 3
- Bit position 2: numbers with 1 at this position: [71, 62, 12, 14] → count = 4
- Bit position 3: numbers with 1 at this position: [24, 62, 12, 14] → count = 4
- Bit position 4: numbers with 1 at this position: [16, 17, 24] → count = 3
The maximum count is 4, which is our answer.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example with candidates = [5, 3, 6]
to illustrate the solution approach.
First, let's convert these numbers to binary:
- 5 = 101
- 3 = 011
- 6 = 110
Step 1: Find maximum bit length The maximum number is 6, which requires 3 bits to represent (110 in binary). So we'll check bit positions 0, 1, and 2.
Step 2: Check each bit position
Bit position 0 (rightmost bit):
- 5 (101): bit at position 0 = 1
- 3 (011): bit at position 0 = 1
- 6 (110): bit at position 0 = 0 Count of 1s = 2 (numbers 5 and 3)
Bit position 1 (middle bit):
- 5 (101): bit at position 1 = 0
- 3 (011): bit at position 1 = 1
- 6 (110): bit at position 1 = 1 Count of 1s = 2 (numbers 3 and 6)
Bit position 2 (leftmost bit):
- 5 (101): bit at position 2 = 1
- 3 (011): bit at position 2 = 0
- 6 (110): bit at position 2 = 1 Count of 1s = 2 (numbers 5 and 6)
Step 3: Find maximum count The maximum count across all bit positions is 2.
Verification:
- At bit position 0, we can combine {5, 3}: 5 & 3 = 101 & 011 = 001 = 1 (> 0) ✓
- At bit position 1, we can combine {3, 6}: 3 & 6 = 011 & 110 = 010 = 2 (> 0) ✓
- At bit position 2, we can combine {5, 6}: 5 & 6 = 101 & 110 = 100 = 4 (> 0) ✓
Each bit position allows us to select 2 numbers maximum, and their AND is always greater than 0 because they all share a 1 at that specific bit position. The answer is 2.
Solution Implementation
1class Solution:
2 def largestCombination(self, candidates: List[int]) -> int:
3 """
4 Find the largest combination of elements where bitwise AND is greater than 0.
5
6 The key insight is that for AND to be > 0, at least one bit position must be 1
7 in all selected numbers. So we count how many numbers have 1 at each bit position.
8
9 Args:
10 candidates: List of positive integers
11
12 Returns:
13 The size of the largest combination with bitwise AND > 0
14 """
15 # Initialize the maximum combination size
16 max_combination_size = 0
17
18 # Find the number of bits needed to represent the largest number
19 max_value = max(candidates)
20 num_bits = max_value.bit_length()
21
22 # Check each bit position from 0 to the highest bit
23 for bit_position in range(num_bits):
24 # Count how many numbers have 1 at the current bit position
25 count_with_bit_set = 0
26 for number in candidates:
27 # Right shift by bit_position and check if the least significant bit is 1
28 if (number >> bit_position) & 1:
29 count_with_bit_set += 1
30
31 # Update the maximum combination size
32 max_combination_size = max(max_combination_size, count_with_bit_set)
33
34 return max_combination_size
35
1class Solution {
2 public int largestCombination(int[] candidates) {
3 // Find the maximum value in the candidates array
4 int maxValue = Arrays.stream(candidates).max().getAsInt();
5
6 // Calculate the number of bits needed to represent the maximum value
7 // This determines how many bit positions we need to check
8 int numBits = Integer.SIZE - Integer.numberOfLeadingZeros(maxValue);
9
10 // Variable to store the maximum count of numbers with same bit set
11 int maxCount = 0;
12
13 // Check each bit position from 0 to numBits-1
14 for (int bitPosition = 0; bitPosition < numBits; bitPosition++) {
15 // Count how many numbers have the current bit position set to 1
16 int currentBitCount = 0;
17
18 // Iterate through all candidates
19 for (int candidate : candidates) {
20 // Check if the bit at current position is set (equals 1)
21 // Right shift by bitPosition and check the least significant bit
22 currentBitCount += (candidate >> bitPosition) & 1;
23 }
24
25 // Update the maximum count if current bit position has more numbers
26 maxCount = Math.max(maxCount, currentBitCount);
27 }
28
29 // Return the maximum size of combination where AND is greater than 0
30 return maxCount;
31 }
32}
33
1class Solution {
2public:
3 int largestCombination(vector<int>& candidates) {
4 // Find the maximum value to determine the highest bit position we need to check
5 int maxValue = *max_element(candidates.begin(), candidates.end());
6
7 // Calculate the number of bits needed to represent the maximum value
8 // __builtin_clz counts leading zeros in a 32-bit integer
9 // 32 - leading_zeros gives us the position of the highest set bit
10 int numBitsToCheck = 32 - __builtin_clz(maxValue);
11
12 int maxCombinationSize = 0;
13
14 // Check each bit position from 0 to the highest bit
15 for (int bitPosition = 0; bitPosition < numBitsToCheck; ++bitPosition) {
16 int countWithBitSet = 0;
17
18 // Count how many numbers have the current bit position set to 1
19 for (int number : candidates) {
20 // Right shift by bitPosition and check if the least significant bit is 1
21 countWithBitSet += (number >> bitPosition) & 1;
22 }
23
24 // The maximum combination size is the maximum count of numbers
25 // that share a common bit position set to 1
26 maxCombinationSize = max(maxCombinationSize, countWithBitSet);
27 }
28
29 return maxCombinationSize;
30 }
31};
32
1/**
2 * Finds the size of the largest combination where the bitwise AND is greater than 0.
3 * The strategy is to count how many numbers have a 1-bit at each bit position,
4 * since the AND of those numbers at that position would be non-zero.
5 *
6 * @param candidates - Array of positive integers to form combinations from
7 * @returns The size of the largest valid combination
8 */
9function largestCombination(candidates: number[]): number {
10 // Find the maximum value to determine the number of bits to check
11 const maxValue: number = Math.max(...candidates);
12
13 // Calculate the number of bits in the binary representation of the maximum value
14 const bitCount: number = maxValue.toString(2).length;
15
16 // Track the maximum count of numbers sharing a common bit
17 let maxCombinationSize: number = 0;
18
19 // Check each bit position from 0 to bitCount-1
20 for (let bitPosition: number = 0; bitPosition < bitCount; bitPosition++) {
21 // Count how many numbers have a 1-bit at the current bit position
22 let currentBitCount: number = 0;
23
24 for (const candidate of candidates) {
25 // Right shift by bitPosition and check if the least significant bit is 1
26 currentBitCount += (candidate >> bitPosition) & 1;
27 }
28
29 // Update the maximum combination size if current count is larger
30 maxCombinationSize = Math.max(maxCombinationSize, currentBitCount);
31 }
32
33 return maxCombinationSize;
34}
35
Time and Space Complexity
Time Complexity: O(n × log M)
The algorithm iterates through each bit position from 0 to max(candidates).bit_length() - 1
. The number of bit positions is log M
where M
is the maximum value in the candidates array. For each bit position, it checks all n
candidates to count how many have that bit set using sum(x >> i & 1 for x in candidates)
, which takes O(n)
time. Therefore, the total time complexity is O(n × log M)
.
Space Complexity: O(1)
The algorithm only uses a constant amount of extra space. The variable ans
stores the maximum count, and the loop variable i
is used for iteration. The generator expression sum(x >> i & 1 for x in candidates)
doesn't create any additional data structures - it processes elements one at a time. No additional arrays, lists, or data structures that scale with input size are created, resulting in constant space complexity.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrectly assuming we need to find an actual combination with maximum AND value
Many people misinterpret this problem as finding the combination that produces the maximum AND result, rather than finding the largest-sized combination where AND > 0.
Wrong approach:
# Trying to maximize the AND result instead of combination size
max_and = 0
for i in range(len(candidates)):
for j in range(i+1, len(candidates)):
max_and = max(max_and, candidates[i] & candidates[j])
Correct understanding: We want the maximum NUMBER of elements that can be combined with AND > 0, not the maximum AND value itself.
2. Using fixed bit width instead of dynamic calculation
Hardcoding a bit width (like 32 or 64) can be inefficient or incorrect for the given input range.
Inefficient approach:
# Always checking 32 bits even if numbers are small
for bit_position in range(32): # Wasteful if max number is small
count = sum((x >> bit_position) & 1 for x in candidates)
Better approach:
# Only check necessary bits based on actual data
num_bits = max(candidates).bit_length()
for bit_position in range(num_bits):
count = sum((x >> bit_position) & 1 for x in candidates)
3. Trying to generate all possible combinations
Attempting to check all possible subsets leads to exponential time complexity O(2^n).
Time-limit-exceeding approach:
from itertools import combinations
max_size = 0
for r in range(1, len(candidates) + 1):
for combo in combinations(candidates, r):
and_result = combo[0]
for num in combo[1:]:
and_result &= num
if and_result > 0:
max_size = r
Efficient O(n * log(max_value)) solution: Count bits at each position as shown in the correct solution.
4. Forgetting edge cases with single elements
When the array has only one element, some implementations might fail.
Potential issue:
# May fail if candidates has only one element
if len(candidates) < 2:
return 0 # Wrong! Single element AND with itself is the element value
Correct handling: The bit-counting approach naturally handles single elements correctly since a single positive integer always has AND > 0 with itself.
Which of the following array represent a max heap?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!