982. Triples with Bitwise AND Equal To Zero
Given an integer array nums, return the number of AND triples.
An AND triple is a triple of indices (i, j, k) such that:
- 0 <= i < nums.length
- 0 <= j < nums.length
- 0 <= k < nums.length
- nums[i] & nums[j] & nums[k] == 0, where & represents the bitwise-AND operator.
示例 1
Input: nums = [2,1,3] Output: 12 Explanation: We could choose the following i, j, k triples: (i=0, j=0, k=1) : 2 & 2 & 1 (i=0, j=1, k=0) : 2 & 1 & 2 (i=0, j=1, k=1) : 2 & 1 & 1 (i=0, j=1, k=2) : 2 & 1 & 3 (i=0, j=2, k=1) : 2 & 3 & 1 (i=1, j=0, k=0) : 1 & 2 & 2 (i=1, j=0, k=1) : 1 & 2 & 1 (i=1, j=0, k=2) : 1 & 2 & 3 (i=1, j=1, k=0) : 1 & 1 & 2 (i=1, j=2, k=0) : 1 & 3 & 2 (i=2, j=0, k=1) : 3 & 2 & 1 (i=2, j=1, k=0) : 3 & 1 & 2
示例 2
Input: nums = [0,0,0] Output: 27
约束条件
- 1 <= nums.length <= 1000
- 0 <= nums[i] < 2^16
解题思路
- 预计算所有成对按位与结果 nums[i] & nums[j] 并统计每个结果出现的次数。
- 对于固定的 nums[k],需要 (nums[i] & nums[j]) & nums[k] == 0。
- 这意味着 (nums[i] & nums[j]) 只能在 nums[k] 为 0 的位上使用 1。
- 构建 freeMask = ~nums[k](限制在 16 位)以表示允许的位。
- 枚举 freeMask 的所有子掩码,并从预计算的表中累加它们的频率。
- 对每个 k 求和得到有效的 (i, j, k) 三元组总数。
代码实现
int countTriplets(int* nums, int numsSize) {
static int cnt[1 << 16]; // reset (static keeps memory; must clear each call)
for (int i = 0; i < (1 << 16); i++) cnt[i] = 0;
// count all pairwise AND results
( i = ; i < numsSize; i++) {
( j = ; j < numsSize; j++) {
cnt[nums[i] & nums[j]]++;
}
}
ans = ;
( k = ; k < numsSize; k++) {
freeMask = (~nums[k]) & ;
sub = freeMask;
() {
ans += cnt[sub];
(sub == ) ;
sub = (sub - ) & freeMask;
}
}
()ans;
}


