The bitwise AND of an array nums
is the bitwise AND of all integers in nums
.
nums = [1, 5, 3]
, the bitwise AND is equal to 1 & 5 & 3 = 1
.nums = [7]
, the bitwise AND is 7
.You are given an array of positive integers candidates
. Compute the bitwise AND for all possible combinations of elements in the candidates
array.
Return the size of the largest combination of candidates
with a bitwise AND greater than 0
.
Example 1:
Input: candidates = [16,17,71,62,12,24,14] Output: 4 Explanation: The combination [16,17,62,24] has a bitwise AND of 16 & 17 & 62 & 24 = 16 > 0. The size of the combination is 4. It can be shown that no combination with a size greater than 4 has a bitwise AND greater than 0. Note that more than one combination may have the largest size. For example, the combination [62,12,24,14] has a bitwise AND of 62 & 12 & 24 & 14 = 8 > 0.
Example 2:
Input: candidates = [8,8] Output: 2 Explanation: The largest combination [8,8] has a bitwise AND of 8 & 8 = 8 > 0. The size of the combination is 2, so we return 2.
Constraints:
1 <= candidates.length <= 105
1 <= candidates[i] <= 107
This problem asks us to find the largest subset of the input array candidates
such that the bitwise AND of all elements in the subset is greater than 0. The solution leverages bit manipulation for efficiency.
Core Idea:
The key observation is that if the bitwise AND of a subset is greater than 0, it means there's at least one bit position where all numbers in the subset have a 1. We can iterate through each bit position (from least significant to most significant) and count how many numbers in candidates
have a 1 in that position. The maximum of these counts will be the answer.
Algorithm:
Find the maximum number: Determine the maximum number (mx
) in the candidates
array. This helps determine the number of bits we need to check.
Iterate through bits: We loop through each bit position from 0 (least significant) up to the number of bits in mx
. We can efficiently determine this using bit manipulation functions like Integer.SIZE - Integer.numberOfLeadingZeros(mx)
in Java or max(candidates).bit_length()
in Python.
Count 1s in each bit position: For each bit position i
, we iterate through candidates
. For each number x
, we check if the i
-th bit is set using the bitwise AND operation: (x >> i) & 1
. If it's 1, we increment a counter cnt
.
Update maximum count: After checking all numbers for a given bit position, we update the maximum count ans
with the current cnt
if cnt
is greater.
Return the maximum count: The final value of ans
represents the size of the largest combination with a bitwise AND greater than 0.
Time Complexity: O(n * log M), where n is the length of candidates
and M is the maximum value in candidates
. The outer loop iterates at most log₂(M) times (number of bits in M), and the inner loop iterates n times.
Space Complexity: O(1). The algorithm uses a constant amount of extra space.
Code Examples (with explanations):
The code examples below are provided in several languages. The core logic remains the same; differences are primarily in syntax and built-in functions for bit manipulation.
Python3:
class Solution:
def largestCombination(self, candidates: List[int]) -> int:
ans = 0
for i in range(max(candidates).bit_length()): # Iterate through bits
cnt = sum(x >> i & 1 for x in candidates) # Count 1s in bit position i
ans = max(ans, cnt) # Update max count
return ans
Java:
class Solution {
public int largestCombination(int[] candidates) {
int mx = Arrays.stream(candidates).max().getAsInt(); //Find max
int m = Integer.SIZE - Integer.numberOfLeadingZeros(mx); //Number of bits
int ans = 0;
for (int i = 0; i < m; ++i) { //Iterate through bits
int cnt = 0;
for (int x : candidates) { //Count 1s
cnt += (x >> i) & 1;
}
ans = Math.max(ans, cnt); //Update max count
}
return ans;
}
}
C++:
class Solution {
public:
int largestCombination(vector<int>& candidates) {
int mx = *max_element(candidates.begin(), candidates.end()); //Find max
int m = 32 - __builtin_clz(mx); //Number of bits (using built-in count leading zeros)
int ans = 0;
for (int i = 0; i < m; ++i) { //Iterate through bits
int cnt = 0;
for (int x : candidates) { //Count 1s
cnt += (x >> i) & 1;
}
ans = max(ans, cnt); //Update max count
}
return ans;
}
};
The other languages (Go and TypeScript) follow a similar structure, utilizing their respective bit manipulation and looping constructs. The core logic of bitwise AND and counting remains consistent across all implementations.