The XOR sum of a list is the bitwise XOR
of all its elements. If the list only contains one element, then its XOR sum will be equal to this element.
[1,2,3,4]
is equal to 1 XOR 2 XOR 3 XOR 4 = 4
, and the XOR sum of [3]
is equal to 3
.You are given two 0-indexed arrays arr1
and arr2
that consist only of non-negative integers.
Consider the list containing the result of arr1[i] AND arr2[j]
(bitwise AND
) for every (i, j)
pair where 0 <= i < arr1.length
and 0 <= j < arr2.length
.
Return the XOR sum of the aforementioned list.
Example 1:
Input: arr1 = [1,2,3], arr2 = [6,5] Output: 0 Explanation: The list = [1 AND 6, 1 AND 5, 2 AND 6, 2 AND 5, 3 AND 6, 3 AND 5] = [0,1,2,0,2,1]. The XOR sum = 0 XOR 1 XOR 2 XOR 0 XOR 2 XOR 1 = 0.
Example 2:
Input: arr1 = [12], arr2 = [4] Output: 4 Explanation: The list = [12 AND 4] = [4]. The XOR sum = 4.
Constraints:
1 <= arr1.length, arr2.length <= 105
0 <= arr1[i], arr2[j] <= 109
This problem asks to find the XOR sum of all pairs' bitwise AND results from two input arrays, arr1
and arr2
. A naive approach would involve iterating through all pairs, calculating the bitwise AND, and then XORing the results. This would have a time complexity of O(n*m), where n and m are the lengths of arr1
and arr2
respectively. However, a significantly more efficient solution exists leveraging bitwise properties.
Optimal Approach:
The key observation is that the XOR operation is associative and commutative. Let's denote the XOR sum of arr1
as xor_arr1
and the XOR sum of arr2
as xor_arr2
. The solution hinges on the following mathematical equivalence:
The XOR sum of all pairs' bitwise AND results is equivalent to the bitwise AND of the XOR sums of the individual arrays. In other words:
Result = xor_arr1 & xor_arr2
This dramatically reduces the computational complexity. We first calculate the XOR sum of each array independently and then perform a single bitwise AND operation on the two results.
Time Complexity Analysis:
xor_arr1
and xor_arr2
takes O(n) and O(m) time respectively, where n is the length of arr1
and m is the length of arr2
.Therefore, the overall time complexity of the optimized solution is O(n + m), which is linear and significantly better than the naive O(n*m) approach.
Space Complexity Analysis:
The algorithm uses only a few constant extra variables to store intermediate results (a
, b
, xor_arr1
, xor_arr2
etc). Thus, the space complexity is O(1), which is constant.
Python3:
from functools import reduce
import operator
class Solution:
def getXORSum(self, arr1: List[int], arr2: List[int]) -> int:
xor_arr1 = reduce(operator.xor, arr1, 0) #Efficient XOR sum calculation
xor_arr2 = reduce(operator.xor, arr2, 0)
return xor_arr1 & xor_arr2
Java:
class Solution {
public int getXORSum(int[] arr1, int[] arr2) {
int xor_arr1 = 0;
for (int num : arr1) {
xor_arr1 ^= num;
}
int xor_arr2 = 0;
for (int num : arr2) {
xor_arr2 ^= num;
}
return xor_arr1 & xor_arr2;
}
}
C++:
#include <numeric>
#include <vector>
class Solution {
public:
int getXORSum(std::vector<int>& arr1, std::vector<int>& arr2) {
int xor_arr1 = std::accumulate(arr1.begin(), arr1.end(), 0, std::bit_xor<int>());
int xor_arr2 = std::accumulate(arr2.begin(), arr2.end(), 0, std::bit_xor<int>());
return xor_arr1 & xor_arr2;
}
};
Go:
func getXORSum(arr1 []int, arr2 []int) int {
xor_arr1 := 0
for _, num := range arr1 {
xor_arr1 ^= num
}
xor_arr2 := 0
for _, num := range arr2 {
xor_arr2 ^= num
}
return xor_arr1 & xor_arr2
}
TypeScript:
function getXORSum(arr1: number[], arr2: number[]): number {
const xor_arr1 = arr1.reduce((acc, curr) => acc ^ curr, 0);
const xor_arr2 = arr2.reduce((acc, curr) => acc ^ curr, 0);
return xor_arr1 & xor_arr2;
}
All these implementations follow the optimized approach, achieving a linear time complexity and constant space complexity. The choice of language only affects the syntax, not the core algorithm.