Count number of subsets having a particular XOR value

Last Updated : 13 Jun, 2026

Given an array of integers arr[] and an integer k, count the number of subsets whose XOR of all elements is equal to k.

Examples : 

Input: arr[] = [6, 9, 4, 2], k = 6
Output: 2
Explanation: The subsets having XOR equal to 6 are {6} and {4, 2}.

Input: arr[] = [1, 2, 3, 4, 5], k = 4
Output: 4
Explanation: The subsets having XOR equal to 4 are {4}, {1, 5}, {1, 2, 3, 4}, and {2, 3, 5}.

Try It Yourself
redirect icon

[Naive Approach] Generate All Subsets - O(2^n) Time and O(n) Space

Generate all subsets considering two choices for every element, either include it in the current subset or exclude it. Recursively explore both possibilities while maintaining the XOR of the selected elements. Whenever all elements have been processed, check whether the current XOR is equal to k. If it is, count the subset.

C++
#include <bits/stdc++.h>
using namespace std;

int solve(int i, int currXor, vector<int> &arr, int k) {
    if (i == arr.size()) {
        return currXor == k;
    }

    // Exclude current element.
    int exclude = solve(i + 1, currXor, arr, k);

    // Include current element.
    int include = solve(i + 1, currXor ^ arr[i], arr, k);

    return exclude + include;
}

int subsetXOR(vector<int> &arr, int k) {
    return solve(0, 0, arr, k);
}

int main() {
    vector<int> arr = {6, 9, 4, 2};
    int k = 6;

    cout << subsetXOR(arr, k);

    return 0;
}
Java
public class GFG {

    static int solve(int i, int currXor, int[] arr, int k) {
        if (i == arr.length) {
            return currXor == k ? 1 : 0;
        }

        // Exclude current element.
        int exclude = solve(i + 1, currXor, arr, k);

        // Include current element.
        int include = solve(i + 1, currXor ^ arr[i], arr, k);

        return exclude + include;
    }

    static int subsetXOR(int[] arr, int k) {
        return solve(0, 0, arr, k);
    }

    public static void main(String[] args) {
        int[] arr = {6, 9, 4, 2};
        int k = 6;

        System.out.println(subsetXOR(arr, k));
    }
}
Python
def solve(i, curr_xor, arr, k):
    if i == len(arr):
        return 1 if curr_xor == k else 0

    # Exclude current element.
    exclude = solve(i + 1, curr_xor, arr, k)

    # Include current element.
    include = solve(i + 1, curr_xor ^ arr[i], arr, k)

    return exclude + include


def subsetXOR(arr, k):
    return solve(0, 0, arr, k)


arr = [6, 9, 4, 2]
k = 6

print(subsetXOR(arr, k))
C#
using System;

class GFG
{
    static int Solve(int i, int currXor, int[] arr, int k)
    {
        if (i == arr.Length)
        {
            return currXor == k ? 1 : 0;
        }

        // Exclude current element.
        int exclude = Solve(i + 1, currXor, arr, k);

        // Include current element.
        int include = Solve(i + 1, currXor ^ arr[i], arr, k);

        return exclude + include;
    }

    static int subsetXOR(int[] arr, int k)
    {
        return Solve(0, 0, arr, k);
    }

    static void Main()
    {
        int[] arr = { 6, 9, 4, 2 };
        int k = 6;

        Console.WriteLine(subsetXOR(arr, k));
    }
}
JavaScript
function solve(i, currXor, arr, k) {
    if (i === arr.length) {
        return currXor === k ? 1 : 0;
    }

    // Exclude current element.
    const exclude = solve(i + 1, currXor, arr, k);

    // Include current element.
    const include = solve(i + 1, currXor ^ arr[i], arr, k);

    return exclude + include;
}

function subsetXOR(arr, k) {
    return solve(0, 0, arr, k);
}

// Driver Code
const arr = [6, 9, 4, 2];
const k = 6;

console.log(subsetXOR(arr, k));

Output
2

[Better Approach] Using Dynamic Programming (Tabulation)

Let dp[i][x] represent the number of subsets formed using the first i elements whose XOR value is x. For each element, we have two choices: exclude it and keep the XOR unchanged, or include it and update the XOR. By filling the table row by row, we can compute the answer without recursion.

C++
#include <bits/stdc++.h>
using namespace std;

int subsetXOR(vector<int> &arr, int k) {
    const int MAX_XOR = 128;
    int n = arr.size();

    vector<vector<int>> dp(n + 1,
                           vector<int>(MAX_XOR, 0));

    dp[0][0] = 1;

    for (int i = 1; i <= n; i++) {
        for (int x = 0; x < MAX_XOR; x++) {
            dp[i][x] = dp[i - 1][x]
                     + dp[i - 1][x ^ arr[i - 1]];
        }
    }

    return dp[n][k];
}

int main() {
    vector<int> arr = {6, 9, 4, 2};
    int k = 6;

    cout << subsetXOR(arr, k);

    return 0;
}
Java
public class GFG {

    static int subsetXOR(int[] arr, int k) {
        final int MAX_XOR = 128;
        int n = arr.length;

        int[][] dp = new int[n + 1][MAX_XOR];

        dp[0][0] = 1;

        for (int i = 1; i <= n; i++) {
            for (int x = 0; x < MAX_XOR; x++) {
                dp[i][x] = dp[i - 1][x]
                         + dp[i - 1][x ^ arr[i - 1]];
            }
        }

        return dp[n][k];
    }

    public static void main(String[] args) {
        int[] arr = {6, 9, 4, 2};
        int k = 6;

        System.out.println(subsetXOR(arr, k));
    }
}
Python
def subsetXOR(arr, k):
    MAX_XOR = 128
    n = len(arr)

    dp = [[0] * MAX_XOR for _ in range(n + 1)]

    dp[0][0] = 1

    for i in range(1, n + 1):
        for x in range(MAX_XOR):
            dp[i][x] = dp[i - 1][x] + dp[i - 1][x ^ arr[i - 1]]

    return dp[n][k]


arr = [6, 9, 4, 2]
k = 6

print(subsetXOR(arr, k))
C#
using System;

class GFG
{
    static int subsetXOR(int[] arr, int k)
    {
        const int MAX_XOR = 128;
        int n = arr.Length;

        int[,] dp = new int[n + 1, MAX_XOR];

        dp[0, 0] = 1;

        for (int i = 1; i <= n; i++)
        {
            for (int x = 0; x < MAX_XOR; x++)
            {
                dp[i, x] = dp[i - 1, x]
                         + dp[i - 1, x ^ arr[i - 1]];
            }
        }

        return dp[n, k];
    }

    static void Main()
    {
        int[] arr = { 6, 9, 4, 2 };
        int k = 6;

        Console.WriteLine(subsetXOR(arr, k));
    }
}
JavaScript
function subsetXOR(arr, k) {
    const MAX_XOR = 128;
    const n = arr.length;

    const dp = Array.from(
        { length: n + 1 },
        () => Array(MAX_XOR).fill(0)
    );

    dp[0][0] = 1;

    for (let i = 1; i <= n; i++) {
        for (let x = 0; x < MAX_XOR; x++) {
            dp[i][x] = dp[i - 1][x]
                     + dp[i - 1][x ^ arr[i - 1]];
        }
    }

    return dp[n][k];
}

// Driver Code
const arr = [6, 9, 4, 2];
const k = 6;

console.log(subsetXOR(arr, k));

Output
2

Time Complexity: O(n * max_xor) - There are n * max_xor states, and each state is computed once.
Auxiliary Space: O(n * max_xor) - A DP table of size n * max_xor is used.

[Expected Approach] Space Optimized Dynamic Programming

In the tabulation approach, dp[i][x] depends only on the previous row dp[i - 1][]. Therefore, instead of storing all n rows, we can keep only the counts for the previous state. For each element, create a new DP array representing the updated counts after considering that element. This reduces the space complexity from O(n * max_xor) to O(max_xor) while maintaining the same time complexity.

C++
#include <bits/stdc++.h>
using namespace std;

int subsetXOR(vector<int> &arr, int k) {
    const int MAX_XOR = 128;

    vector<int> dp(MAX_XOR, 0);
    dp[0] = 1;

    for (int num : arr) {
        vector<int> newDp(MAX_XOR, 0);

        for (int x = 0; x < MAX_XOR; x++) {

            // Exclude current element.
            newDp[x] += dp[x];

            // Include current element.
            newDp[x ^ num] += dp[x];
        }

        dp = move(newDp);
    }

    return dp[k];
}

int main() {
    vector<int> arr = {6, 9, 4, 2};
    int k = 6;

    cout << subsetXOR(arr, k);

    return 0;
}
Java
public class GFG {

    static int subsetXOR(int[] arr, int k) {
        final int MAX_XOR = 128;

        int[] dp = new int[MAX_XOR];
        dp[0] = 1;

        for (int num : arr) {
            int[] newDp = new int[MAX_XOR];

            for (int x = 0; x < MAX_XOR; x++) {

                // Exclude current element.
                newDp[x] += dp[x];

                // Include current element.
                newDp[x ^ num] += dp[x];
            }

            dp = newDp;
        }

        return dp[k];
    }

    public static void main(String[] args) {
        int[] arr = {6, 9, 4, 2};
        int k = 6;

        System.out.println(subsetXOR(arr, k));
    }
}
Python
def subsetXOR(arr, k):
    MAX_XOR = 128

    dp = [0] * MAX_XOR
    dp[0] = 1

    for num in arr:
        new_dp = [0] * MAX_XOR

        for x in range(MAX_XOR):

            # Exclude current element.
            new_dp[x] += dp[x]

            # Include current element.
            new_dp[x ^ num] += dp[x]

        dp = new_dp

    return dp[k]


arr = [6, 9, 4, 2]
k = 6

print(subsetXOR(arr, k))
C#
using System;

class GFG
{
    static int subsetXOR(int[] arr, int k)
    {
        const int MAX_XOR = 128;

        int[] dp = new int[MAX_XOR];
        dp[0] = 1;

        foreach (int num in arr)
        {
            int[] newDp = new int[MAX_XOR];

            for (int x = 0; x < MAX_XOR; x++)
            {
                // Exclude current element.
                newDp[x] += dp[x];

                // Include current element.
                newDp[x ^ num] += dp[x];
            }

            dp = newDp;
        }

        return dp[k];
    }

    static void Main()
    {
        int[] arr = { 6, 9, 4, 2 };
        int k = 6;

        Console.WriteLine(subsetXOR(arr, k));
    }
}
JavaScript
function subsetXOR(arr, k) {
    const MAX_XOR = 128;

    let dp = new Array(MAX_XOR).fill(0);
    dp[0] = 1;

    for (const num of arr) {
        const newDp = new Array(MAX_XOR).fill(0);

        for (let x = 0; x < MAX_XOR; x++) {

            // Exclude current element.
            newDp[x] += dp[x];

            // Include current element.
            newDp[x ^ num] += dp[x];
        }

        dp = newDp;
    }

    return dp[k];
}

// Driver Code
const arr = [6, 9, 4, 2];
const k = 6;

console.log(subsetXOR(arr, k));

Output
2

Time Complexity: O(n * max_xor) - For each element, all possible XOR values are processed once.
Auxiliary Space: O(max_xor) - Only two arrays of size max_xor are used.


Comment