↓Skip to main content
  1. LeetCode/

LeetCode 3513: Number of Unique XOR Triplets I

·2 mins· ·
LeetCode Biweekly-Contest Medium Bit-Manipulation Unsolved
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents
LeetCode Bi-Weekly Contest 154 - This article is part of a series.
Part 2: This Article

Meta Data
#

Difficulty: medium First Attempt: 2025-04-12

  • Total time: 20:00.00 (TLE)

Intuition
#

My initial idea was to use a triple for-loop (O(n^3)) to iterate through all possible combinations of nums, and store the XOR results in a set called seen. However, this approach would obviously result in a TLE (Time Limit Exceeded) due to the three nested loops.

Then, I attempted to apply Digit DP, thinking it could help reduce duplicate calculations. For example:

  • (0, 0, 0) → 3 XOR 3 XOR 3 = 3
  • (0, 0, 1) → 3 XOR 3 XOR 1 = 1
  • (0, 0, 2) → 3 XOR 3 XOR 2 = 2
  • (0, 1, 2) → 3 XOR 1 XOR 2 = 0

We don’t need to recalculate expressions like 3 XOR 3 if the result has already been cached using lru_cache.

However, the issue is that, unlike many classic Digit DP problems where the result space is relatively small, the set of possible XOR results in this problem is quite large. As a result, lru_cache suffers from a high cache miss rate, and the performance gain is minimal. Eventually, this still leads to TLE.

I believe the only feasible solution here involves bit manipulation, though I haven’t found a clear explanation or an optimal approach yet.

Approach
#

class Solution:
    def uniqueXorTriplets(self, nums: List[int]) -> int:
        
        from functools import lru_cache

        n = len(nums)

        @lru_cache(None)
        def dfs(position, num_index, xor_result):
            if position == 3:
                return {xor_result}

            result = set()
            for idx in range(num_index, n):
                result.update(
                    dfs(
                        position + 1,
                        idx,
                        xor_result ^ nums[idx]
                    )
                )

            return result

        return len(dfs(0, 0, 0))

Findings
#

  1. The set of possible xor_result values is too large, resulting in a high cache miss rate in this approach, which eventually leads to a TLE.

Encountered Problems
#

LeetCode Bi-Weekly Contest 154 - This article is part of a series.
Part 2: This Article

Related

LeetCode 222: Count Complete Tree Nodes
·2 mins
LeetCode Medium Binary-Search Bit-Manipulation Tree Binary-Tree
LeetCode 222 note: in a complete tree, equal leftmost depths on both sides mean one side is perfect, counted as 2^h - 1, for O(log² n)
LeetCode 397: Integer Replacement
·2 mins
LeetCode Medium Dynamic-Programming Greedy Bit-Manipulation Memoization
LeetCode 397 note: even numbers are always halved; for odd numbers try +1 and -1 with memoized recursion, since n is too large for an n-sized array
LeetCode 473: Matchsticks to Square
·2 mins
LeetCode Medium Array Dynamic-Programming Backtracking Bit-Manipulation
LeetCode 473 note: the total must be divisible by 4; place sticks from longest to shortest into one of four sides, skipping a side that would overflow or that equals a side already tried
LeetCode 187: Repeated DNA Sequences
·1 min
LeetCode Medium Hash-Table String Bit-Manipulation Sliding-Window
LeetCode 187 note: count every length-10 substring in a hash map and return those seen more than once
LeetCode 137: Single Number II
·2 mins
LeetCode Medium Array Bit-Manipulation
LeetCode 137 note: with everything else appearing three times, count the 1s at each bit modulo 3; the leftover bits form the answer, minding negatives
LeetCode 287: Find the Duplicate Number
·2 mins
LeetCode Medium Array Two-Pointers Binary-Search Bit-Manipulation
LeetCode 287 note: treat i -> nums[i] as a linked list; the duplicate is the cycle entry, found with Floyd’s algorithm in O(1) space without modifying the array