title: Bitwise XOR of All Pairings slug: bitwise-xor-of-all-pairings difficulty: medium leetcode_id: 2425 leetcode_url: https://leetcode.com/problems/bitwise-xor-of-all-pairings/ categories: - arrays - math patterns: - slug: greedy is_optimal: true function_signature: "def xor_all_nums(nums1: list[int], nums2: list[int]) -> int:" test_cases: visible: - input: { nums1: [2, 1, 3], nums2: [10, 2, 5, 0] } expected: 13 - input: { nums1: [1, 2], nums2: [3, 4] } expected: 0 hidden: - input: { nums1: [1], nums2: [1] } expected: 0 - input: { nums1: [5], nums2: [3, 7] } expected: 0 - input: { nums1: [1, 2, 3], nums2: [4] } expected: 4 - input: { nums1: [0], nums2: [0, 0, 0] } expected: 0 - input: { nums1: [1, 1], nums2: [2, 2] } expected: 0 - input: { nums1: [7, 8, 9], nums2: [1, 2, 3] } expected: 0 description: | You are given two **0-indexed** arrays, `nums1` and `nums2`, consisting of non-negative integers. Let there be another array, `nums3`, which contains the bitwise XOR of **all pairings** of integers between `nums1` and `nums2` (every integer in `nums1` is paired with every integer in `nums2` **exactly once**). Return *the **bitwise XOR** of all integers in* `nums3`. constraints: | - `1 <= nums1.length, nums2.length <= 10^5` - `0 <= nums1[i], nums2[j] <= 10^9` examples: - input: "nums1 = [2,1,3], nums2 = [10,2,5,0]" output: "13" explanation: "A possible nums3 array is [8,0,7,2,11,3,4,1,9,1,6,3]. The bitwise XOR of all these numbers is 13." - input: "nums1 = [1,2], nums2 = [3,4]" output: "0" explanation: "All possible pairs of bitwise XORs are nums1[0] ^ nums2[0], nums1[0] ^ nums2[1], nums1[1] ^ nums2[0], and nums1[1] ^ nums2[1]. Thus, one possible nums3 array is [2,5,1,6]. 2 ^ 5 ^ 1 ^ 6 = 0, so we return 0." explanation: intuition: | At first glance, this problem seems to require generating all `m * n` pairwise XORs (where `m = len(nums1)` and `n = len(nums2)`), then XORing them all together. With constraints up to `10^5` for both arrays, that's potentially `10^10` operations — far too slow. The key insight comes from a fundamental property of XOR: **a value XORed with itself cancels out** (`x ^ x = 0`). This means if any value appears an **even number of times** in the final XOR, it contributes nothing to the result. Think of it like this: imagine laying out all pairwise XORs in a grid. Each element `nums1[i]` appears in **exactly `n` pairs** (once with each element of `nums2`). Similarly, each element `nums2[j]` appears in **exactly `m` pairs**. When we XOR all pairs together, we're effectively XORing each `nums1[i]` a total of `n` times, and each `nums2[j]` a total of `m` times. If `n` is even, all `nums1` elements cancel out. If `m` is even, all `nums2` elements cancel out. This reduces the problem to simple parity checks on the array lengths. approach: | We solve this using **XOR properties and parity analysis**: **Step 1: Understand the contribution of each element** - Each element in `nums1` is XORed with every element in `nums2`, so it appears in `len(nums2)` pairs - Each element in `nums2` is XORed with every element in `nums1`, so it appears in `len(nums1)` pairs - When we XOR all pairs, each `nums1[i]` is XORed `len(nums2)` times total   **Step 2: Apply the cancellation property** - If `len(nums2)` is even, each `nums1[i]` appears an even number of times and cancels out - If `len(nums2)` is odd, each `nums1[i]` appears an odd number of times and contributes once - The same logic applies to `nums2` elements based on `len(nums1)`   **Step 3: Compute the result based on parity** - `result = 0` - If `len(nums2)` is odd: XOR all elements of `nums1` into result - If `len(nums1)` is odd: XOR all elements of `nums2` into result - Return the final result   This elegant solution avoids generating any pairs at all, working in O(m + n) time. common_pitfalls: - title: The Brute Force Trap description: | The naive approach generates all `m * n` pairwise XORs: ```python for a in nums1: for b in nums2: result ^= (a ^ b) ``` With `m, n <= 10^5`, this results in up to `10^10` operations — a guaranteed **Time Limit Exceeded**. The mathematical insight about parity is essential to solve this efficiently. wrong_approach: "Nested loops generating all pairs" correct_approach: "Use parity to determine which elements contribute" - title: Forgetting Both Arrays Can Contribute description: | It's easy to focus on just one array's contribution. Remember: - `nums1` contributes if `len(nums2)` is **odd** - `nums2` contributes if `len(nums1)` is **odd** Both conditions can be true simultaneously! For example, if both arrays have odd lengths, elements from **both** arrays contribute to the final XOR. wrong_approach: "Only checking one array's length parity" correct_approach: "Check both len(nums1) and len(nums2) independently" - title: Confusing Which Length Matters description: | A subtle error is checking the wrong length for each array: - `nums1` elements appear `len(nums2)` times (not `len(nums1)` times) - `nums2` elements appear `len(nums1)` times (not `len(nums2)` times) If you check `len(nums1) % 2` to decide whether to include `nums1`, you'll get the wrong answer. The **other** array's length determines the contribution. wrong_approach: "Checking len(nums1) % 2 for nums1's contribution" correct_approach: "Check len(nums2) % 2 for nums1's contribution" key_takeaways: - "**XOR cancellation**: `x ^ x = 0` — values appearing an even number of times cancel out entirely" - "**Parity analysis**: When elements repeat based on array lengths, check if the count is odd or even to determine contribution" - "**Avoid unnecessary computation**: Mathematical insight can reduce O(n^2) or worse problems to O(n)" - "**Bit manipulation patterns**: Many XOR problems have elegant solutions based on fundamental properties like `x ^ x = 0` and `x ^ 0 = x`" time_complexity: "O(m + n). We iterate through each array at most once, where `m = len(nums1)` and `n = len(nums2)`." space_complexity: "O(1). We only use a single variable to accumulate the XOR result." solutions: - approach_name: Parity-Based XOR is_optimal: true code: | def xor_all_nums(nums1: list[int], nums2: list[int]) -> int: result = 0 len1, len2 = len(nums1), len(nums2) # Each nums1 element appears len2 times in all pairs # If len2 is odd, it contributes to the final XOR if len2 % 2 == 1: for num in nums1: result ^= num # Each nums2 element appears len1 times in all pairs # If len1 is odd, it contributes to the final XOR if len1 % 2 == 1: for num in nums2: result ^= num return result explanation: | **Time Complexity:** O(m + n) — Single pass through each array at most once. **Space Complexity:** O(1) — Only one variable used. We leverage the XOR cancellation property: elements appearing an even number of times contribute nothing. Each element in `nums1` appears `len(nums2)` times, and vice versa. We only XOR elements whose appearance count is odd. - approach_name: Pythonic One-Liner is_optimal: true code: | from functools import reduce from operator import xor def xor_all_nums(nums1: list[int], nums2: list[int]) -> int: # XOR nums1 if len(nums2) is odd, XOR nums2 if len(nums1) is odd return ( (reduce(xor, nums1, 0) if len(nums2) % 2 else 0) ^ (reduce(xor, nums2, 0) if len(nums1) % 2 else 0) ) explanation: | **Time Complexity:** O(m + n) — Same as the explicit version. **Space Complexity:** O(1) — Constant extra space. A more compact version using `reduce` to XOR all elements. The logic is identical: include `nums1`'s XOR if `len(nums2)` is odd, include `nums2`'s XOR if `len(nums1)` is odd. - approach_name: Brute Force is_optimal: false code: | def xor_all_nums(nums1: list[int], nums2: list[int]) -> int: result = 0 # XOR every possible pair for a in nums1: for b in nums2: result ^= (a ^ b) return result explanation: | **Time Complexity:** O(m * n) — Nested loops over both arrays. **Space Complexity:** O(1) — Only tracking result. This directly computes the XOR of all pairs. While correct, it's far too slow for large inputs (up to `10^10` operations). Included to illustrate why the mathematical insight is necessary. This will cause TLE on LeetCode.