{x}
blog image

Count Triplets That Can Form Two Arrays of Equal XOR

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] <= 108

Solution Explanation for Count Triplets That Can Form Two Arrays of Equal XOR

This problem asks us to find the number of triplets (i, j, k) in an array arr such that the XOR sum of arr[i]...arr[j-1] equals the XOR sum of arr[j]...arr[k].

Approach:

The most straightforward approach is to use three nested loops to iterate through all possible triplets (i, j, k) and check the condition. This brute-force method calculates the XOR sums for each subarray and compares them. However, this is inefficient.

A more efficient approach involves using prefix XOR sums. We create a prefix XOR array pre, where pre[i] stores the XOR sum of arr[0]...arr[i-1]. This allows us to calculate the XOR sum of any subarray in O(1) time using the formula:

XOR(arr[i]...arr[j-1]) = pre[j] ^ pre[i]

With this optimization, we can still use nested loops but the XOR calculation becomes much faster.

Time Complexity Analysis:

  • Brute-force approach: O(n³), where n is the length of the array. This is because we have three nested loops.
  • Prefix XOR approach: O(n³). While we've optimized the XOR calculation, we still have three nested loops iterating through all possible triplets.

Space Complexity Analysis:

  • Both approaches have a space complexity of O(n) due to the prefix XOR array pre.

Code Explanation (Python):

class Solution:
    def countTriplets(self, arr: List[int]) -> int:
        n = len(arr)
        pre = [0] * (n + 1)  # Prefix XOR array. pre[0] is initialized to 0.
        for i in range(n):
            pre[i + 1] = pre[i] ^ arr[i]  # Calculate prefix XOR sums.
 
        ans = 0
        for i in range(n - 1):
            for j in range(i + 1, n):
                for k in range(j, n):
                    a = pre[j] ^ pre[i]  # XOR sum of arr[i]...arr[j-1]
                    b = pre[k + 1] ^ pre[j] # XOR sum of arr[j]...arr[k]
                    if a == b:
                        ans += 1
        return ans
 

The code first calculates the prefix XOR array. Then, it iterates through all possible triplets (i, j, k) using three nested loops. For each triplet, it calculates a and b using the prefix XOR array and increments the counter ans if a equals b.

Code in Other Languages:

The logic remains the same across different programming languages; only the syntax varies. The Java, C++, and Go code examples provided in the original response implement the same prefix XOR approach with minor syntactic differences. They all have the same O(n³) time complexity and O(n) space complexity.

Possible Optimizations (Not Implemented in the Provided Code):

While the prefix XOR approach significantly improves the XOR calculation, the overall time complexity remains cubic. Further optimization might be possible using more advanced techniques, but they would likely increase the code complexity significantly and might not be worthwhile for the constraints given (array length up to 300).