Facebook Pixel

2425. Bitwise XOR of All Pairings

MediumBit ManipulationBrainteaserArray
Leetcode Link

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 in nums1 appears an odd number of times in the final XOR calculation
  • If nums2 has an even length, each element in nums1 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 in nums1
  • If len(nums1) is odd, XOR all elements in nums2
  • Return the combined XOR result
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

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 from nums1 appears exactly len(nums2) times (3 times in this example)
  • Each element x from nums2 appears exactly len(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 if len(nums2) is odd
  • Elements from nums2 contribute to the final result only if len(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:

  1. Initialize the result variable: Start with ans = 0 to accumulate our XOR result.

  2. 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 with ans:
      if len(nums2) & 1:
          for v in nums1:
              ans ^= v
  3. 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 with ans:
      if len(nums1) & 1:
          for v in nums2:
              ans ^= v
  4. 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) where m and n are the lengths of nums1 and nums2
  • 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 Evaluator

Example 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 in nums1, which takes O(m) time
  • If len(nums1) is odd, we iterate through all elements in nums2, which takes O(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 in nums1
  • If nums2 has odd length, XOR all elements in nums2

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 appears len(nums2) times in the pairs
  • Each element in nums2 appears len(nums1) times in the pairs

Therefore:

  • Check len(nums2) to determine if nums1 elements contribute
  • Check len(nums1) to determine if nums2 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.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

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

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More