LeetCode Entry
1442. Count Triplets That Can Form Two Arrays of Equal XOR
Number (i,j,k) where xor arr[i..j] = xor arr[j..k] manipulation
1442. Count Triplets That Can Form Two Arrays of Equal XOR medium
blog post
substack
youtube

Join me on Telegram
https://t.me/leetcode_daily_unstoppable/622
Problem TLDR
Number (i,j,k) where xor arr[i..j] = xor arr[j..k] #medium #bit_manipulation
Intuition
Start with the brute-force solution, it will be accepted.
for (j in i + 1..k)
a = a ^ arr[j]
b = ikXor ^ a
if (a == b) res++
Some optimizations:
- we have precomputed total xor between
i..kand now ifa = xor [i..j - 1]thenb = xor [i..k] ^ a.
Let’s inline a and b in the if (a == b) equation:
if (a ^ arr[j] == ikXor ^ (a ^ arr[j])) ...
We can safely remove ^ a ^ arr[j] from the left and the right parts, leaving it like if (0 == ikXor). As this now independent of j, we can just collapse the third loop into ` if (0 == ikXor) res += k - i`.
(There is one more optimization possible: store xors prefixes count in a HashMap, this will reduce the time to O(n))
Approach
Using sumOf and .map().sum() helps to reduce some lines of code.
Complexity
-
Time complexity: \(O(n^2)\)
-
Space complexity: \(O(1)\)
Code
fun countTriplets(arr: IntArray): Int =
arr.indices.sumOf { i ->
var ikXor = 0
(i..<arr.size).sumOf { k ->
ikXor = ikXor xor arr[k]
if (0 == ikXor) k - i else 0
}
}
pub fn count_triplets(arr: Vec<i32>) -> i32 {
(0..arr.len()).map(|i| {
let mut ik_xor = 0;
(i..arr.len()).map(|k| {
ik_xor ^= arr[k];
if ik_xor == 0 { k - i } else { 0 }
}).sum::<usize>()
}).sum::<usize>() as _
}