3215. Count Triplets with Even XOR Set Bits II 🔒
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 1
s) 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.
-
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 theXOR
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 usingXOR
conjunction. -
Counting Parities: We can break down the problem by first counting how many elements in each of the arrays
a
,b
, andc
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. -
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 of0
. - Parities
(0, 1, 1)
and(1, 0, 1)
also make a sum of0
.
- Parities
-
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:
-
Parity Calculation: For each of the arrays
a
,b
, andc
, we calculate and store the parity of the number of1
s (set bits) in the binary representation of each element. This is done using thebit_count()
method and the& 1
operation, which gives0
for an even count and1
for an odd count. -
Use of Counters: We use Python's
Counter
from thecollections
module to efficiently count how many elements belong to each parity (even or odd). This results in three counterscnt1
,cnt2
, andcnt3
for arraysa
,b
, andc
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)
-
Combining Parities: We iterate over all possible parity combinations for the three arrays. We check combinations
(i, j, k)
wherei
,j
, andk
can be0
or1
. -
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 toTrue
when the sum is even. -
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]
, andcnt3[k]
. This product is then added to the cumulative resultans
.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]
-
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 EvaluatorExample 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
-
Calculate Parity for Each Element:
- For array
a
:1
in binary is01
, which has1
set bit (odd parity).2
in binary is10
, which has1
set bit (odd parity).
- For array
b
:3
in binary is11
, which has2
set bits (even parity).4
in binary is100
, which has1
set bit (odd parity).
- For array
c
:5
in binary is101
, which has2
set bits (even parity).6
in binary is110
, which has2
set bits (even parity).
- For array
-
Count Parities Using Counters:
cnt1
fora
: odd parity2
(0: 0, 1: 2
)cnt2
forb
: even parity1
, odd parity1
(0: 1, 1: 1
)cnt3
forc
: even parity2
(0: 2, 1: 0
)
-
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
- Parity
- For parity
-
Accumulate Valid Combinations:
- Only
(1, 1, 0)
matches, so add 4 to the result.
- Only
-
Return the Result:
- The total number of valid triplets is
4
.
- The total number of valid triplets is
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.
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
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!