Facebook Pixel

3215. Count Triplets with Even XOR Set Bits II 🔒

MediumBit ManipulationArray
Leetcode Link

Problem Description

You are given three integer arrays a, b, and c. The task is to determine the number of triplets (a[i], b[j], c[k]) such that the bitwise XOR of the elements in each triplet results in a number that has an even number of set bits. A set bit is a bit that is '1' in the binary representation of a number.

Intuition

To solve this problem, we focus on the relationship between the number of set bits (or 1s) in the binary representation of numbers. Specifically, we are interested in the parity (evenness or oddness) of these set bits after performing a bitwise XOR on elements from the arrays.

  1. Understanding XOR and Parity: The bitwise XOR operation between two numbers results in a number where bits are set if they differ in the operands. The parity of set bits in the XOR result is related to the parity of set bits in the operands. The goal is to ensure that the total number of set bits across three numbers has an even parity when using XOR conjunction.

  2. Counting Parities: We can break down the problem by first counting how many elements in each of the arrays a, b, and c have an even number of set bits. Similarly, we count for those with an odd number. This gives us a way to represent the parity distribution in each array.

  3. Combination of Parities: To form a triplet (a[i], b[j], c[k]) that results in an XOR with an even number of set bits, the sum of the parities from the three chosen numbers must also be even. Specifically:

    • Parities (0, 0, 0) and (1, 1, 0) make a sum of 0.
    • Parities (0, 1, 1) and (1, 0, 1) also make a sum of 0.
  4. Calculate Results: By using combinations of the counted parities, we can efficiently compute how many such triplets can be formed. Each combination of these parities is counted and multiplied to produce a solution count for valid triplets.

The solution effectively leverages counting and combination analysis, minimizing the need for excessive iteration or recalculation.

Solution Approach

To implement the solution effectively, we utilize bit manipulation and counting principles. Here's how the solution is structured:

  1. Parity Calculation: For each of the arrays a, b, and c, we calculate and store the parity of the number of 1s (set bits) in the binary representation of each element. This is done using the bit_count() method and the & 1 operation, which gives 0 for an even count and 1 for an odd count.

  2. Use of Counters: We use Python's Counter from the collections module to efficiently count how many elements belong to each parity (even or odd). This results in three counters cnt1, cnt2, and cnt3 for arrays a, b, and c respectively. Each counter will tell us how many numbers have an even parity (0) and how many have an odd parity (1).

    cnt1 = Counter(x.bit_count() & 1 for x in a)
    cnt2 = Counter(x.bit_count() & 1 for x in b)
    cnt3 = Counter(x.bit_count() & 1 for x in c)
  3. Combining Parities: We iterate over all possible parity combinations for the three arrays. We check combinations (i, j, k) where i, j, and k can be 0 or 1.

  4. Even Parity Check: The sum of the parities (i + j + k) needs to be even for a valid triplet. This condition is checked with the expression (i + j + k) & 1 ^ 1, which evaluates to True when the sum is even.

  5. Accumulating Results: For each valid triplet of parities, we compute the number of possible combinations by multiplying their respective counts from cnt1[i], cnt2[j], and cnt3[k]. This product is then added to the cumulative result ans.

    ans = 0
    for i in range(2):
        for j in range(2):
            for k in range(2):
                if (i + j + k) & 1 ^ 1:
                    ans += cnt1[i] * cnt2[j] * cnt3[k]
  6. Return the Result: Finally, the accumulated ans represents the total number of triplets with the desired property, which is returned as the solution.

This approach efficiently calculates the result with minimal complexity, using bit-level operations and counting structures to handle the input arrays.

Ready to land your dream job?

Unlock your dream job with a 2-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a simple example to illustrate the solution approach.

Consider three arrays:

  • a = [1, 2]
  • b = [3, 4]
  • c = [5, 6]

Step-by-Step Solution

  1. Calculate Parity for Each Element:

    • For array a:
      • 1 in binary is 01, which has 1 set bit (odd parity).
      • 2 in binary is 10, which has 1 set bit (odd parity).
    • For array b:
      • 3 in binary is 11, which has 2 set bits (even parity).
      • 4 in binary is 100, which has 1 set bit (odd parity).
    • For array c:
      • 5 in binary is 101, which has 2 set bits (even parity).
      • 6 in binary is 110, which has 2 set bits (even parity).
  2. Count Parities Using Counters:

    • cnt1 for a: odd parity 2 (0: 0, 1: 2)
    • cnt2 for b: even parity 1, odd parity 1 (0: 1, 1: 1)
    • cnt3 for c: even parity 2 (0: 2, 1: 0)
  3. Combine Parities and Check for Even Parity:

    • For parity (0, 0, 0), (1, 1, 0), (0, 1, 1), (1, 0, 1), ensure the sum is even.
    • Example calculation:
      • Parity (0, 0, 0):
        • cnt1[0] * cnt2[0] * cnt3[0] = 0 * 1 * 2 = 0
      • Parity (1, 1, 0):
        • cnt1[1] * cnt2[1] * cnt3[0] = 2 * 1 * 2 = 4
  4. Accumulate Valid Combinations:

    • Only (1, 1, 0) matches, so add 4 to the result.
  5. Return the Result:

    • The total number of valid triplets is 4.

This simple walkthrough demonstrates how the solution leverages parity counting and bitwise operations to efficiently arrive at the desired result.

Solution Implementation

1from typing import List
2from collections import Counter
3
4class Solution:
5    def tripletCount(self, a: List[int], b: List[int], c: List[int]) -> int:
6        # Count numbers in each list based on whether they have an even or odd number of 1s in binary representation
7        cnt1 = Counter(x.bit_count() & 1 for x in a)
8        cnt2 = Counter(x.bit_count() & 1 for x in b)
9        cnt3 = Counter(x.bit_count() & 1 for x in c)
10      
11        ans = 0
12        # Iterate through all combinations of parity for triplet (i, j, k)
13        # i, j, k can be 0 (even) or 1 (odd)
14        for i in range(2):
15            for j in range(2):
16                for k in range(2):
17                    # Check if the sum of parities is even
18                    # (i + j + k) & 1 is 0 if the sum is even, XOR with 1 results in zero
19                    if (i + j + k) & 1 ^ 1:
20                        # Increment answer by the product of counts of i, j, k
21                        ans += cnt1[i] * cnt2[j] * cnt3[k]
22        return ans
23
1class Solution {
2    public long tripletCount(int[] a, int[] b, int[] c) {
3        // Arrays to count numbers with odd and even 1-bits in each input array
4        int[] cnt1 = new int[2]; // Count for array 'a'
5        int[] cnt2 = new int[2]; // Count for array 'b'
6        int[] cnt3 = new int[2]; // Count for array 'c'
7
8        // Count numbers with odd and even number of 1-bits in array 'a'
9        for (int x : a) {
10            ++cnt1[Integer.bitCount(x) & 1];
11        }
12
13        // Count numbers with odd and even number of 1-bits in array 'b'
14        for (int x : b) {
15            ++cnt2[Integer.bitCount(x) & 1];
16        }
17
18        // Count numbers with odd and even number of 1-bits in array 'c'
19        for (int x : c) {
20            ++cnt3[Integer.bitCount(x) & 1];
21        }
22
23        long totalTriplets = 0; // Initialize the result count
24      
25        // Iterate over all possible combinations of odd/even counts
26        for (int i = 0; i < 2; ++i) { // Odd/even count from array 'a'
27            for (int j = 0; j < 2; ++j) { // Odd/even count from array 'b'
28                for (int k = 0; k < 2; ++k) { // Odd/even count from array 'c'
29                    // Check if the sum of odd/even statuses is even
30                    if ((i + j + k) % 2 == 0) {
31                        // Add to total count the triplets forming even parity
32                        totalTriplets += 1L * cnt1[i] * cnt2[j] * cnt3[k];
33                    }
34                }
35            }
36        }
37      
38        return totalTriplets; // Return the total count of valid triplets
39    }
40}
41
1class Solution {
2public:
3    long long tripletCount(vector<int>& a, vector<int>& b, vector<int>& c) {
4        // Arrays to count numbers with odd and even number of 1-bits in their binary representation
5        int countA[2]{};
6        int countB[2]{};
7        int countC[2]{};
8      
9        // Count the numbers in vector a with odd/even 1-bits
10        for (int num : a) {
11            ++countA[__builtin_popcount(num) & 1];
12        }
13      
14        // Count the numbers in vector b with odd/even 1-bits
15        for (int num : b) {
16            ++countB[__builtin_popcount(num) & 1];
17        }
18      
19        // Count the numbers in vector c with odd/even 1-bits
20        for (int num : c) {
21            ++countC[__builtin_popcount(num) & 1];
22        }
23      
24        long long result = 0;
25      
26        // Calculate the number of valid combinations based on odd/even parity sum check
27        for (int i = 0; i < 2; ++i) {
28            for (int j = 0; j < 2; ++j) {
29                for (int k = 0; k < 2; ++k) {
30                    // Ensure the sum of parities is even
31                    if ((i + j + k) % 2 == 0) {
32                        result += 1LL * countA[i] * countB[j] * countC[k];
33                    }
34                }
35            }
36        }
37      
38        return result;
39    }
40};
41
1// Function to calculate the number of valid triplets (a, b, c) such that 
2// the sum of their bit counts is even.
3function tripletCount(a: number[], b: number[], c: number[]): number {
4    // Arrays to store counts of numbers with even and odd bit counts, respectively.
5    const cnt1: [number, number] = [0, 0];
6    const cnt2: [number, number] = [0, 0];
7    const cnt3: [number, number] = [0, 0];
8
9    // Populate cnt1 with counts of even and odd bit counts for array 'a'.
10    for (const x of a) {
11        ++cnt1[bitCount(x) & 1];
12    }
13
14    // Populate cnt2 with counts of even and odd bit counts for array 'b'.
15    for (const x of b) {
16        ++cnt2[bitCount(x) & 1];
17    }
18
19    // Populate cnt3 with counts of even and odd bit counts for array 'c'.
20    for (const x of c) {
21        ++cnt3[bitCount(x) & 1];
22    }
23
24    // Variable to store the final count of valid triplets.
25    let ans: number = 0;
26
27    // Iterate over all combinations of even and odd bit counts.
28    for (let i = 0; i < 2; ++i) {
29        for (let j = 0; j < 2; ++j) {
30            for (let k = 0; k < 2; ++k) {
31                // Check if the sum of indices gives an even result.
32                if ((i + j + k) % 2 === 0) {
33                    // Multiply the combinations and add to the answer.
34                    ans += cnt1[i] * cnt2[j] * cnt3[k];
35                }
36            }
37        }
38    }
39
40    return ans;
41}
42
43// Function to count the number of 1-bits in a number's binary representation.
44function bitCount(i: number): number {
45    // Subtract values to group bits and sum their counts.
46    i = i - ((i >>> 1) & 0x55555555);
47    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
48    i = (i + (i >>> 4)) & 0x0f0f0f0f;
49  
50    // Accumulate results with larger bit-width shifts.
51    i = i + (i >>> 8);
52    i = i + (i >>> 16);
53
54    // Return the accumulated count of 1-bits.
55    return i & 0x3f;
56}
57

Time and Space Complexity

The time complexity of the code is O(n), where n is the combined length of arrays a, b, and c. This is because each element of the arrays is processed a constant number of times, specifically to calculate the bit count and to build the Counter objects.

The space complexity is O(1), as only a fixed number of counters are used regardless of the input size, and no additional data structures that grow with the input size are utilized.

Learn more about how to find time and space complexity quickly.


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

A person thinks of a number between 1 and 1000. You may ask any number questions to them, provided that the question can be answered with either "yes" or "no".

What is the minimum number of questions you needed to ask so that you are guaranteed to know the number that the person is thinking?


Recommended Readings

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


Load More