Intuition¶
Every triplet XOR is of the form (a XOR b) XOR c. First collect all pairwise
XORs with i <= j, then XOR each of those with every array element. Values are
at most 1500, so pairwise XORs fit in [0, 2047] and a fixed boolean array
works.
Approach: Pair XOR Set + Triple Extension¶
- Mark all
nums[i] XOR nums[j]for0 <= i <= j < ninpairXorSet. - For each marked pair XOR
x, markx XOR numfor everynuminnumsintripleXorSet. - Return the number of
trueentries intripleXorSet.
Complexity¶
- Time complexity: $$O(n^2 + n \cdot U)$$, where
nisnums.lengthandU = 2048is the XOR value universe — pairwise enumeration plus one pass over marked pair XORs timesn. - Space complexity: $$O(U)$$ for the two boolean arrays.
Code¶
Go¶
func uniqueXorTriplets(nums []int) int {
n := len(nums)
pairXorSet := [2048]bool{}
for i := range n {
for j := i; j < n; j++ {
pairXorSet[nums[i]^nums[j]] = true
}
}
tripleXorSet := [2048]bool{}
for i := range 2048 {
if !pairXorSet[i] {
continue
}
for _, num := range nums {
tripleXorSet[i^num] = true
}
}
ans := 0
for _, seen := range tripleXorSet {
if seen {
ans++
}
}
return ans
}
Rust¶
impl Solution {
pub fn unique_xor_triplets(nums: Vec<i32>) -> i32 {
let n = nums.len();
let mut pair_xor_set = [false; 2048];
for i in 0..n {
for j in i..n {
pair_xor_set[(nums[i] ^ nums[j]) as usize] = true;
}
}
let mut triple_xor_set = [false; 2048];
let mut ans = 0;
for i in 0..2048 {
if !pair_xor_set[i] {
continue;
}
for &num in &nums {
triple_xor_set[i ^ (num as usize)] = true;
}
}
triple_xor_set.iter().filter(|&&num| num).count() as i32
}
}