Triples with Bitwise AND Equal To Zero

Pair-AND frequency lookup — for each i, count j,k with (a[j] & a[k] & a[i]) == 0 via a precomputed pairwise table.

Hard
Time O(n^2 + n * 2^16) Space O(2^16)
LeetCode
4 min read
bit-manipulation hash-map counting

Problem#

Count triplets (i, j, k) of indices into nums (with repetition allowed and order mattering) such that nums[i] & nums[j] & nums[k] == 0.

Examples#

  • [2,1,3]12.
  • [0,0,0]27.

Constraints#

  • 1 <= nums.length <= 1000, 0 <= nums[i] < 2^16.

Approach#

Precompute pairAnd[v] = number of ordered (i, j) with nums[i] & nums[j] == v. Then for each k, sum pairAnd[v] over all v with v & nums[k] == 0. Enumerating those v cleverly uses the submask trick: iterate all submasks of ~nums[k] capped to 16 bits.

Solution#

Triples with Bitwise AND Equal To Zero
class Solution {
public:
int countTriplets(vector<int>& nums) {
const int N = 1 << 16;
vector<int> pairAnd(N, 0);
for (int a : nums)
for (int b : nums)
++pairAnd[a & b];
int ans = 0;
for (int c : nums) {
int comp = (~c) & (N - 1);
for (int sub = comp; ; sub = (sub - 1) & comp) {
ans += pairAnd[sub];
if (sub == 0) break;
}
}
return ans;
}
};

Editorial#

(a & b & c) == 0 is equivalent to (a & b) being a submask of ~c. Building the AND distribution of pairs is O(n^2). Iterating submasks of ~c for each c totals at most O(n * 3^16) in theory but is far less in practice because most masks are small.

Complexity#

  • Time: ~O(n^2 + n * 2^16).
  • Space: O(2^16).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.