Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1863. Sum of All Subset XOR Totals - Leetcode Solution

Code Implementation

class Solution:
    def subsetXORSum(self, nums):
        def dfs(i, curr_xor):
            if i == len(nums):
                return curr_xor
            # Include nums[i]
            with_curr = dfs(i + 1, curr_xor ^ nums[i])
            # Exclude nums[i]
            without_curr = dfs(i + 1, curr_xor)
            return with_curr + without_curr
        return dfs(0, 0)
      
class Solution {
public:
    int subsetXORSum(vector<int>& nums) {
        return dfs(nums, 0, 0);
    }
private:
    int dfs(const vector<int>& nums, int i, int curr_xor) {
        if (i == nums.size()) {
            return curr_xor;
        }
        int with_curr = dfs(nums, i + 1, curr_xor ^ nums[i]);
        int without_curr = dfs(nums, i + 1, curr_xor);
        return with_curr + without_curr;
    }
};
      
class Solution {
    public int subsetXORSum(int[] nums) {
        return dfs(nums, 0, 0);
    }

    private int dfs(int[] nums, int i, int currXor) {
        if (i == nums.length) {
            return currXor;
        }
        int withCurr = dfs(nums, i + 1, currXor ^ nums[i]);
        int withoutCurr = dfs(nums, i + 1, currXor);
        return withCurr + withoutCurr;
    }
}
      
var subsetXORSum = function(nums) {
    function dfs(i, currXor) {
        if (i === nums.length) {
            return currXor;
        }
        let withCurr = dfs(i + 1, currXor ^ nums[i]);
        let withoutCurr = dfs(i + 1, currXor);
        return withCurr + withoutCurr;
    }
    return dfs(0, 0);
};
      

Problem Description

Given an array of positive integers nums, your task is to find the sum of the XOR totals of every subset of nums. The XOR total of a subset is the result of applying the bitwise XOR operation to all its elements (if the subset is empty, its XOR total is 0). Return the sum of all these XOR totals.

  • Each subset can use each element at most once (do not reuse elements).
  • There is only one valid solution for each input.
  • Input: nums is a list of integers (length up to 12, values up to 20).

Thought Process

The problem asks us to consider all possible subsets of the array nums and compute the XOR of each subset, then sum all these results. At first glance, this seems like a brute-force problem: for each subset, calculate its XOR total, then sum them up.

Since the number of subsets for an array of length n is 2^n, a brute-force approach could work for small arrays. However, for larger arrays, this approach becomes inefficient. We need to consider whether there's a more clever way to avoid recalculating the same XORs or to leverage properties of XOR and subsets to optimize our solution.

The key insight is that for each element, we have a choice: either include it in the current subset or not. This naturally leads to a recursive or backtracking approach, where at each step we branch into two possibilities.

Solution Approach

We can solve this problem efficiently using recursion (depth-first search) to generate all subsets and calculate their XOR totals. Here's how:

  1. Recursive function: Define a function that takes two parameters: the current index i in nums, and the current XOR value curr_xor of the chosen subset so far.
  2. Base case: If we've considered all elements (i.e., i == len(nums)), return curr_xor because we've formed a subset.
  3. Recursive case: For each element, we have two choices:
    • Include nums[i] in the subset: call the function with i+1 and curr_xor ^ nums[i].
    • Exclude nums[i] from the subset: call the function with i+1 and curr_xor unchanged.
    The sum for this subtree is the sum of the results from both choices.
  4. Initial call: Start the recursion from index 0 and XOR value 0 (the empty subset).
  5. Return the total: The answer is the sum returned by the recursive process.

This approach ensures we consider all possible subsets and accumulate their XOR totals. Since the input size is small (up to 12 elements), this method is efficient enough.

Example Walkthrough

Let's walk through an example with nums = [1, 3].

  • All subsets are: [], [1], [3], [1, 3]
  • Their XOR totals:
    • []: 0
    • [1]: 1
    • [3]: 3
    • [1,3]: 1 ^ 3 = 2
  • Sum: 0 + 1 + 3 + 2 = 6

Our recursive function explores both choices at each element:

  • Start at index 0, curr_xor = 0
  • Include 1: index 1, curr_xor = 1
    • Include 3: index 2, curr_xor = 1 ^ 3 = 2 (return 2)
    • Exclude 3: index 2, curr_xor = 1 (return 1)
  • Exclude 1: index 1, curr_xor = 0
    • Include 3: index 2, curr_xor = 0 ^ 3 = 3 (return 3)
    • Exclude 3: index 2, curr_xor = 0 (return 0)
  • Add up: 2 + 1 + 3 + 0 = 6

Time and Space Complexity

  • Brute-force approach:
    • There are 2^n subsets for an array of length n.
    • Calculating the XOR for each subset takes up to O(n) time, so total time is O(n * 2^n).
  • Optimized recursive approach:
    • We avoid recalculating the XOR for each subset from scratch by passing the current XOR down recursively.
    • There are still 2^n recursive calls, but each call does only O(1) work.
    • So, total time complexity is O(2^n).
    • Space complexity is O(n) for the recursion stack.

Summary

The problem asks us to sum the XOR totals of all subsets of an array. By using a recursive approach that explores all subset combinations (including or excluding each element), we efficiently compute the answer in O(2^n) time. This is feasible given the input constraints. The solution leverages the natural structure of subsets and the properties of XOR, making it both elegant and efficient for the problem size.