Given an array of integers arr
.
We want to select three indices i
, j
and k
where (0 <= i < j <= k < arr.length)
.
Let's define a
and b
as follows:
a = arr[i] ^ arr[i + 1] ^ ... ^ arr[j - 1]
b = arr[j] ^ arr[j + 1] ^ ... ^ arr[k]
Note that ^ denotes the bitwise-xor operation.
Return the number of triplets (i
, j
and k
) Where a == b
.
Example 1:
Input: arr = [2,3,1,6,7]
Output: 4
Explanation: The triplets are (0,1,2), (0,2,2), (2,3,4) and (2,4,4)
Example 2:
Input: arr = [1,1,1,1,1]
Output: 10
Constraints:
1 <= arr.length <= 300
1 <= arr[i] <= 10^8
Array, Math, Bit Manipulation
This problem is equivalent to "search for a sub-array whose elements XOR = 0", since O(n^2)
complexity to find all sub-arrays of length x
whose xor is 0, and add x-1
onto the result counter.
We can use hash tables to avoid to find i
to save time. Based on the observation that i
, which is equal to k
.
- Time complexity:
$$O(n^2)$$ - Space complexity:
$$O(n)$$
- Time complexity:
$$O(n)$$ - Space complexity:
$$O(n)$$
func countTriplets(arr []int) int {
ans, s, count, total := 0, 0, map[int]int{}, map[int]int{} // index:xor, index:count_i
for k, v := range arr {
if m, ok := count[s^v]; ok {
ans += m*k - total[s^v]
}
count[s]++
total[s] += k
s ^= v
}
return ans
}
func countTriplets(arr []int) int {
ans, prefix := 0, make([]int, len(arr)+1)
for i, v := range arr {
prefix[i+1] = prefix[i] ^ v
}
for i := 1; i < len(arr); i++ {
for k := i + 1; k <= len(arr); k++ {
if prefix[i-1] == prefix[k] { // prefix[i-1]^prefix[k] == 0
ans += k - i // k-(i-1)+1
}
}
}
return ans
}