{x}
blog image

Sum of All Subset XOR Totals

The XOR total of an array is defined as the bitwise XOR of all its elements, or 0 if the array is empty.

  • For example, the XOR total of the array [2,5,6] is 2 XOR 5 XOR 6 = 1.

Given an array nums, return the sum of all XOR totals for every subset of nums

Note: Subsets with the same elements should be counted multiple times.

An array a is a subset of an array b if a can be obtained from b by deleting some (possibly zero) elements of b.

 

Example 1:

Input: nums = [1,3]
Output: 6
Explanation: The 4 subsets of [1,3] are:
- The empty subset has an XOR total of 0.
- [1] has an XOR total of 1.
- [3] has an XOR total of 3.
- [1,3] has an XOR total of 1 XOR 3 = 2.
0 + 1 + 3 + 2 = 6

Example 2:

Input: nums = [5,1,6]
Output: 28
Explanation: The 8 subsets of [5,1,6] are:
- The empty subset has an XOR total of 0.
- [5] has an XOR total of 5.
- [1] has an XOR total of 1.
- [6] has an XOR total of 6.
- [5,1] has an XOR total of 5 XOR 1 = 4.
- [5,6] has an XOR total of 5 XOR 6 = 3.
- [1,6] has an XOR total of 1 XOR 6 = 7.
- [5,1,6] has an XOR total of 5 XOR 1 XOR 6 = 2.
0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28

Example 3:

Input: nums = [3,4,5,6,7,8]
Output: 480
Explanation: The sum of all XOR totals for every subset is 480.

 

Constraints:

  • 1 <= nums.length <= 12
  • 1 <= nums[i] <= 20

Solution Explanation for LeetCode 1863: Sum of All Subset XOR Totals

This problem asks to find the sum of XOR totals for all subsets of a given array nums. Let's explore two efficient solutions: binary enumeration and depth-first search (DFS).

Solution 1: Binary Enumeration

This approach leverages the fact that subsets can be represented using bits. Each bit in a binary number corresponds to an element in nums. If the bit is 1, the element is included in the subset; otherwise, it's excluded.

Algorithm:

  1. Iterate through all possible subsets: We iterate from 0 to 2n - 1 (where n is the length of nums), representing all possible subsets using their binary representations.

  2. Calculate XOR total for each subset: For each binary number (subset representation), we iterate through nums. If the corresponding bit is set (1), we XOR the element into the current XOR total.

  3. Sum the XOR totals: We accumulate the XOR total of each subset into a final sum.

Time Complexity: O(n * 2n) - We iterate through 2n subsets, and for each subset, we perform O(n) XOR operations.

Space Complexity: O(1) - Constant extra space is used.

Code (Python):

class Solution:
    def subsetXORSum(self, nums: List[int]) -> int:
        ans = 0
        n = len(nums)
        for i in range(1 << n): # Iterate through all subsets (0 to 2^n -1)
            s = 0
            for j in range(n):
                if (i >> j) & 1: # Check if j-th bit is set in i
                    s ^= nums[j]
            ans += s
        return ans

The code in other languages (Java, C++, Go, TypeScript, JavaScript) follows a similar pattern, differing only in syntax.

Solution 2: Depth-First Search (DFS)

DFS provides a recursive way to explore all subsets.

Algorithm:

  1. Recursive function dfs(index, current_xor):

    • index: The current index being considered in nums.
    • current_xor: The running XOR total for the subset built so far.
  2. Base Case: If index reaches the end of nums, add current_xor to the total sum.

  3. Recursive Steps:

    • Exclude: Recursively call dfs(index + 1, current_xor) (don't include the current element).
    • Include: Recursively call dfs(index + 1, current_xor ^ nums[index]) (include the current element and XOR it).

Time Complexity: O(2n) - Each recursive call explores two branches, leading to 2n total calls.

Space Complexity: O(n) - The maximum depth of the recursion stack is n (the length of nums).

Code (Python):

class Solution:
    def subsetXORSum(self, nums: List[int]) -> int:
        total_xor_sum = 0
 
        def dfs(index, current_xor):
            nonlocal total_xor_sum
            if index == len(nums):
                total_xor_sum += current_xor
                return
            dfs(index + 1, current_xor)  # Exclude
            dfs(index + 1, current_xor ^ nums[index])  # Include
 
        dfs(0, 0)
        return total_xor_sum
 

Again, other language implementations will be structurally similar.

Choosing the Best Solution:

Both solutions correctly solve the problem. The DFS approach might be slightly more intuitive for those comfortable with recursion. However, the binary enumeration method often performs better in practice due to its iterative nature and avoidance of recursive function calls, especially for larger input sizes. The asymptotic complexity difference isn't significant for this problem's constrained input size (nums.length <= 12).