Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions problems/3513-number-of-unique-xor-triplets-i/analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 3513. Number of Unique XOR Triplets I

[LeetCode Link](https://leetcode.com/problems/number-of-unique-xor-triplets-i/)

Difficulty: Medium
Topics: Array, Math, Bit Manipulation
Acceptance Rate: 34.9%

## Hints

### Hint 1

The brute force is to enumerate every triplet `(i, j, k)` with `i <= j <= k`, XOR the three values, and collect the results in a set. With `n` up to `10^5` that is on the order of `n^3` combinations — far too many. Before writing any loops, ask yourself: does the *specific structure* of the input (a permutation of `1..n`) let us skip the enumeration entirely? Think in terms of which bit patterns are reachable rather than which index triplets exist.

### Hint 2

The condition `i <= j <= k` allows indices to repeat. That is the key freedom: you can pick the same element twice. Since `x XOR x = 0`, choosing `nums[i] == nums[j]` collapses the triplet to a single element `nums[k]`. So every individual value is trivially reachable, and the real question becomes: what is the full set of values reachable as an XOR of *one or three* distinct elements drawn from `{1, 2, ..., n}`?

### Hint 3

Because the array always contains the numbers `1` and `2` (whenever `n >= 3`), you have enough "building blocks" to flip any bit combination. XOR-ing subsets of `{1, ..., n}` can produce every value from `0` up to the largest number representable with the same number of bits as `n`. That upper bound is `2^b - 1`, where `b` is the number of bits in `n`. So for `n >= 3` the answer is simply `2^b` (the count of values `0 .. 2^b - 1`). Only the tiny cases `n = 1` and `n = 2` behave differently and must be handled by hand.

## Approach

Observe that the constraint `i <= j <= k` permits repeated indices, so any element can appear an even number of times inside a triplet. Two equal picks cancel via XOR (`x XOR x = 0`), which means:

- Picking all three equal gives each single value `v`.
- Picking two equal and one different gives every single value as well.
- Picking three distinct gives genuine 3-way XORs.

So the reachable set is exactly the set of values obtainable by XOR-ing one or three chosen numbers from `{1, 2, ..., n}`.

Now use the small-value building blocks. For `n >= 3`, the numbers `1` and `2` (and more) are present, and XOR combinations of the numbers `1..n` cover the entire range `[0, 2^b - 1]`, where `b` is the bit length of `n`. Intuitively, with distinct powers-of-two-ish contributors you can toggle each of the `b` low bits independently, filling out every value with at most `b` bits. Therefore the number of unique triplet XOR values is `2^b`.

Handle the two degenerate cases explicitly:

- `n == 1`: the only element is `1`, so the only triplet is `1 XOR 1 XOR 1 = 1`. Answer is `1`.
- `n == 2`: elements are `{1, 2}`. Enumerating gives values `{1, 2}`. Answer is `2`.

For everything else, compute the bit length `b` of `n` and return `1 << b`.

**Worked example (`nums = [3,1,2]`, `n = 3`):** `n` in binary is `11`, so `b = 2` and the answer is `2^2 = 4`. Indeed the reachable values are `{0, 1, 2, 3}` — matching the expected output.

## Complexity Analysis

Time Complexity: O(log n) — a single pass over the bits of `n` to find its bit length. (We don't even need to read the array beyond its length.)
Space Complexity: O(1) — only a couple of integer counters.

## Edge Cases

- `n == 1`: Only one element (`1`); the sole triplet XORs to `1`. Returns `1`. Missing this special-case would over-count.
- `n == 2`: Only `1` bit's worth of numbers combined don't fill a full power-of-two range; the true answer is `2`, not `2^b`. Must be handled separately.
- `n == 3`: The first case where the general `2^b` formula kicks in (`b = 2`, answer `4`); a good sanity check that the boundary between special-cased and general logic is correct.
- Powers of two boundaries (e.g. `n = 4`, `n = 8`): the bit length jumps here, so the answer jumps to the next power of two. Verifying these confirms the bit-length computation is off-by-one free.
73 changes: 73 additions & 0 deletions problems/3513-number-of-unique-xor-triplets-i/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
number: "3513"
frontend_id: "3513"
title: "Number of Unique XOR Triplets I"
slug: "number-of-unique-xor-triplets-i"
difficulty: "Medium"
topics:
- "Array"
- "Math"
- "Bit Manipulation"
acceptance_rate: 3488.1
is_premium: false
created_at: "2026-07-23T03:52:36.142002+00:00"
fetched_at: "2026-07-23T03:52:36.142002+00:00"
link: "https://leetcode.com/problems/number-of-unique-xor-triplets-i/"
date: "2026-07-23"
---

# 3513. Number of Unique XOR Triplets I

You are given an integer array `nums` of length `n`, where `nums` is a **permutation** of the numbers in the range `[1, n]`.

A **XOR triplet** is defined as the XOR of three elements `nums[i] XOR nums[j] XOR nums[k]` where `i <= j <= k`.

Return the number of **unique** XOR triplet values from all possible triplets `(i, j, k)`.



**Example 1:**

**Input:** nums = [1,2]

**Output:** 2

**Explanation:**

The possible XOR triplet values are:

* `(0, 0, 0) -> 1 XOR 1 XOR 1 = 1`
* `(0, 0, 1) -> 1 XOR 1 XOR 2 = 2`
* `(0, 1, 1) -> 1 XOR 2 XOR 2 = 1`
* `(1, 1, 1) -> 2 XOR 2 XOR 2 = 2`



The unique XOR values are `{1, 2}`, so the output is 2.

**Example 2:**

**Input:** nums = [3,1,2]

**Output:** 4

**Explanation:**

The possible XOR triplet values include:

* `(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`



The unique XOR values are `{0, 1, 2, 3}`, so the output is 4.



**Constraints:**

* `1 <= n == nums.length <= 105`
* `1 <= nums[i] <= n`
* `nums` is a permutation of integers from `1` to `n`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

// 3513. Number of Unique XOR Triplets I
//
// Approach: Because triplet indices satisfy i <= j <= k, indices may repeat,
// so a pair of equal picks cancels under XOR (x ^ x = 0). This makes every
// single element reachable, and the reachable set overall is exactly the set
// of XORs of one or three numbers drawn from the permutation {1, ..., n}.
//
// For n >= 3 the numbers 1 and 2 (and larger) are present, and XOR-combining
// values in [1, n] fills the whole range [0, 2^b - 1] where b is the bit
// length of n. Hence there are 2^b unique values. The tiny cases n == 1 and
// n == 2 don't fill a full power-of-two range and are handled directly.
//
// Time: O(log n) to compute the bit length of n. Space: O(1).
func uniqueXorTriplets(nums []int) int {
n := len(nums)

if n == 1 {
return 1
}
if n == 2 {
return 2
}

// Bit length of n: number of bits needed to represent n.
bits := 0
for x := n; x > 0; x >>= 1 {
bits++
}
return 1 << bits
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import "testing"

func TestSolution(t *testing.T) {
tests := []struct {
name string
nums []int
expected int
}{
{"example 1: nums = [1,2] -> {1,2}", []int{1, 2}, 2},
{"example 2: nums = [3,1,2] -> {0,1,2,3}", []int{3, 1, 2}, 4},
{"edge case: single element n=1", []int{1}, 1},
{"edge case: n=4 power of two boundary", []int{4, 3, 2, 1}, 8},
{"edge case: n=7 fills 3-bit range", []int{7, 6, 5, 4, 3, 2, 1}, 8},
{"edge case: n=8 crosses to 4-bit range", []int{8, 7, 6, 5, 4, 3, 2, 1}, 16},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := uniqueXorTriplets(tt.nums)
if result != tt.expected {
t.Errorf("uniqueXorTriplets(%v) = %d, want %d", tt.nums, result, tt.expected)
}
})
}
}