2425. Bitwise XOR of All Pairings
Problem Description
You have two arrays nums1
and nums2
, both containing non-negative integers and indexed starting from 0.
You need to create a third array nums3
that contains the XOR results of all possible pairs between nums1
and nums2
. This means:
- Take each element from
nums1
- XOR it with every element in
nums2
- Put all these XOR results into
nums3
For example, if nums1 = [a, b]
and nums2 = [x, y]
, then nums3
would contain: [a⊕x, a⊕y, b⊕x, b⊕y]
.
Your task is to return the XOR of all elements in nums3
.
The key insight is that when you XOR the same number twice, the result is 0 (a ⊕ a = 0
). Each element in nums1
gets XORed with every element in nums2
, so:
- If
nums2
has an odd length, each element innums1
appears an odd number of times in the final XOR calculation - If
nums2
has an even length, each element innums1
appears an even number of times (canceling out to 0)
The same logic applies for elements in nums2
with respect to the length of nums1
.
The solution checks:
- If
len(nums2)
is odd, XOR all elements innums1
- If
len(nums1)
is odd, XOR all elements innums2
- Return the combined XOR result
Intuition
Let's think about what happens when we form all pairs and XOR them together. If we have nums1 = [a, b]
and nums2 = [x, y, z]
, the pairs would be:
a⊕x, a⊕y, a⊕z, b⊕x, b⊕y, b⊕z
When we XOR all these together: (a⊕x) ⊕ (a⊕y) ⊕ (a⊕z) ⊕ (b⊕x) ⊕ (b⊕y) ⊕ (b⊕z)
Due to the associative and commutative properties of XOR, we can rearrange this as:
(a ⊕ a ⊕ a) ⊕ (b ⊕ b ⊕ b) ⊕ (x ⊕ x) ⊕ (y ⊕ y) ⊕ (z ⊕ z)
Notice that:
- Each element
a
fromnums1
appears exactlylen(nums2)
times (3 times in this example) - Each element
x
fromnums2
appears exactlylen(nums1)
times (2 times in this example)
The crucial property of XOR is that x ⊕ x = 0
. This means:
- If an element appears an even number of times, it contributes 0 to the final result
- If an element appears an odd number of times, it contributes its value exactly once
Therefore:
- Elements from
nums1
contribute to the final result only iflen(nums2)
is odd - Elements from
nums2
contribute to the final result only iflen(nums1)
is odd
This transforms our complex problem into a simple check: just XOR the appropriate arrays based on the parity of the other array's length!
Solution Approach
The implementation follows directly from our intuition about XOR properties and element frequency:
-
Initialize the result variable: Start with
ans = 0
to accumulate our XOR result. -
Check if
nums2
length is odd:- Use bitwise AND with 1:
len(nums2) & 1
returns 1 if odd, 0 if even - If odd, each element in
nums1
appears an odd number of times in the final calculation - XOR all elements in
nums1
withans
:if len(nums2) & 1: for v in nums1: ans ^= v
- Use bitwise AND with 1:
-
Check if
nums1
length is odd:- Similarly, use
len(nums1) & 1
to check parity - If odd, each element in
nums2
appears an odd number of times - XOR all elements in
nums2
withans
:if len(nums1) & 1: for v in nums2: ans ^= v
- Similarly, use
-
Return the result: The variable
ans
now contains the XOR of all elements that appear an odd number of times.
The beauty of this solution is its efficiency:
- Time Complexity:
O(m + n)
wherem
andn
are the lengths ofnums1
andnums2
- Space Complexity:
O(1)
as we only use a single variable to store the result
We avoid creating the actual nums3
array (which would have m × n
elements) by leveraging the mathematical properties of XOR to directly compute the final result.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to see how this solution works.
Example: nums1 = [2, 3]
and nums2 = [1, 6, 5]
Step 1: Form all XOR pairs (conceptually)
If we were to create nums3
with all XOR pairs:
2 ⊕ 1 = 3
2 ⊕ 6 = 4
2 ⊕ 5 = 7
3 ⊕ 1 = 2
3 ⊕ 6 = 5
3 ⊕ 5 = 6
So nums3 = [3, 4, 7, 2, 5, 6]
and XORing all elements: 3 ⊕ 4 ⊕ 7 ⊕ 2 ⊕ 5 ⊕ 6 = 1
Step 2: Apply our optimized approach
Instead of creating nums3
, we check the array lengths:
len(nums1) = 2
(even)len(nums2) = 3
(odd)
Initialize ans = 0
Since len(nums2) = 3
is odd (3 & 1 = 1):
- Each element in
nums1
appears 3 times in the XOR calculation - We XOR all elements in
nums1
:ans = 0 ⊕ 2 ⊕ 3 = 1
Since len(nums1) = 2
is even (2 & 1 = 0):
- Each element in
nums2
appears 2 times (even) in the XOR calculation - These cancel out to 0, so we don't XOR elements from
nums2
Result: ans = 1
Verification: Let's verify why this works by regrouping the XOR operations:
- Original:
(2⊕1) ⊕ (2⊕6) ⊕ (2⊕5) ⊕ (3⊕1) ⊕ (3⊕6) ⊕ (3⊕5)
- Regrouped:
(2⊕2⊕2) ⊕ (3⊕3⊕3) ⊕ (1⊕1) ⊕ (6⊕6) ⊕ (5⊕5)
- Since
1⊕1 = 0
,6⊕6 = 0
,5⊕5 = 0
, we get:2 ⊕ 3 = 1
The optimized solution correctly gives us the same answer without creating the intermediate array!
Solution Implementation
1from typing import List
2
3
4class Solution:
5 def xorAllNums(self, nums1: List[int], nums2: List[int]) -> int:
6 """
7 Calculate XOR of all possible pairs (num1, num2) where num1 is from nums1 and num2 is from nums2.
8
9 Key insight: Each element in nums1 appears len(nums2) times in the pairs,
10 and each element in nums2 appears len(nums1) times in the pairs.
11 Due to XOR properties (a ^ a = 0), an element contributes to the final result
12 only if it appears an odd number of times.
13
14 Args:
15 nums1: First list of integers
16 nums2: Second list of integers
17
18 Returns:
19 XOR result of all possible pairs
20 """
21 result = 0
22
23 # If length of nums2 is odd, each element in nums1 appears odd times
24 # Therefore, XOR all elements in nums1
25 if len(nums2) & 1: # Using bitwise AND to check if odd (equivalent to len(nums2) % 2 == 1)
26 for num in nums1:
27 result ^= num
28
29 # If length of nums1 is odd, each element in nums2 appears odd times
30 # Therefore, XOR all elements in nums2
31 if len(nums1) & 1: # Using bitwise AND to check if odd
32 for num in nums2:
33 result ^= num
34
35 return result
36
1class Solution {
2 /**
3 * Computes the XOR of all possible pairs between two arrays.
4 *
5 * The algorithm leverages the property that XOR-ing a number with itself
6 * an even number of times results in 0. Each element in nums1 appears
7 * nums2.length times in the final XOR, and each element in nums2 appears
8 * nums1.length times.
9 *
10 * @param nums1 First integer array
11 * @param nums2 Second integer array
12 * @return XOR result of all possible pairs (nums1[i] ^ nums2[j])
13 */
14 public int xorAllNums(int[] nums1, int[] nums2) {
15 int result = 0;
16
17 // If nums2 has odd length, each element in nums1 appears odd times
18 // in the XOR calculation, so include all elements from nums1
19 if (nums2.length % 2 == 1) {
20 for (int value : nums1) {
21 result ^= value;
22 }
23 }
24
25 // If nums1 has odd length, each element in nums2 appears odd times
26 // in the XOR calculation, so include all elements from nums2
27 if (nums1.length % 2 == 1) {
28 for (int value : nums2) {
29 result ^= value;
30 }
31 }
32
33 return result;
34 }
35}
36
1class Solution {
2public:
3 int xorAllNums(vector<int>& nums1, vector<int>& nums2) {
4 int result = 0;
5
6 // If nums2 has odd length, each element in nums1 appears odd times in the pairs
7 // XOR of odd occurrences of a number equals the number itself
8 if (nums2.size() % 2 == 1) {
9 for (int num : nums1) {
10 result ^= num;
11 }
12 }
13
14 // If nums1 has odd length, each element in nums2 appears odd times in the pairs
15 // XOR of odd occurrences of a number equals the number itself
16 if (nums1.size() % 2 == 1) {
17 for (int num : nums2) {
18 result ^= num;
19 }
20 }
21
22 return result;
23 }
24};
25
1/**
2 * Calculates the XOR of all possible pairs between two arrays.
3 * Each element in nums1 is paired with every element in nums2.
4 *
5 * The key insight: Each element in nums1 appears nums2.length times in the pairs,
6 * and each element in nums2 appears nums1.length times in the pairs.
7 * Since XOR of even occurrences cancels out, we only need to XOR elements
8 * that appear an odd number of times.
9 *
10 * @param nums1 - First array of numbers
11 * @param nums2 - Second array of numbers
12 * @returns The XOR result of all possible pairs
13 */
14function xorAllNums(nums1: number[], nums2: number[]): number {
15 let result: number = 0;
16
17 // If nums2 has odd length, each element in nums1 appears odd times
18 // So we need to include XOR of all nums1 elements
19 if (nums2.length % 2 !== 0) {
20 result ^= nums1.reduce((accumulator: number, current: number) => accumulator ^ current, 0);
21 }
22
23 // If nums1 has odd length, each element in nums2 appears odd times
24 // So we need to include XOR of all nums2 elements
25 if (nums1.length % 2 !== 0) {
26 result ^= nums2.reduce((accumulator: number, current: number) => accumulator ^ current, 0);
27 }
28
29 return result;
30}
31
Time and Space Complexity
Time Complexity: O(m + n)
, where m
is the length of nums1
and n
is the length of nums2
.
The algorithm consists of two conditional blocks:
- If
len(nums2)
is odd, we iterate through all elements innums1
, which takesO(m)
time - If
len(nums1)
is odd, we iterate through all elements innums2
, which takesO(n)
time
In the worst case, both conditions are true, resulting in iterating through both arrays once, giving us O(m + n)
time complexity.
Space Complexity: O(1)
The algorithm only uses a single variable ans
to store the XOR result, regardless of the input size. No additional data structures are created that scale with the input, making the space complexity constant.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Attempting to Generate All Pairs Explicitly
The Pitfall: A natural first approach might be to actually create all the XOR pairs and then XOR them together:
def xorAllNums_naive(nums1, nums2):
result = 0
for num1 in nums1:
for num2 in nums2:
result ^= (num1 ^ num2)
return result
Why it's problematic:
- Time complexity becomes O(m × n) instead of O(m + n)
- For large arrays, this creates unnecessary computational overhead
- Misses the elegant mathematical insight about XOR properties
The Solution:
Recognize that XOR operations can be rearranged. When you XOR all pairs, each element from nums1
gets XORed with every element in nums2
. Due to associative and commutative properties of XOR, you can group operations by element frequency rather than computing each pair.
2. Misunderstanding When Elements Contribute to the Result
The Pitfall: Incorrectly thinking that:
- If
nums1
has odd length, XOR all elements innums1
- If
nums2
has odd length, XOR all elements innums2
This reverses the actual logic!
Why it happens: Confusion about which array's length determines the frequency of the other array's elements.
The Solution: Remember the relationship:
- Each element in
nums1
appearslen(nums2)
times in the pairs - Each element in
nums2
appearslen(nums1)
times in the pairs
Therefore:
- Check
len(nums2)
to determine ifnums1
elements contribute - Check
len(nums1)
to determine ifnums2
elements contribute
3. Using Modulo Instead of Bitwise AND for Parity Check
The Pitfall:
Using len(nums2) % 2 == 1
instead of len(nums2) & 1
Why it matters: While both are functionally correct, the bitwise operation is:
- Slightly faster (though the difference is minimal in Python)
- More idiomatic in competitive programming
- Demonstrates understanding of bit manipulation
The Solution:
Use len(array) & 1
which returns:
- 1 if the length is odd (last bit is 1)
- 0 if the length is even (last bit is 0)
This is a micro-optimization but shows attention to detail in algorithmic solutions.
What is the best way of checking if an element exists in a sorted array once in terms of time complexity? Select the best that applies.
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!