01. XOR Pairs less than K
β GFG solution to the Count Pairs with XOR Less Than K problem: efficiently count pairs whose XOR is less than k using Binary Trie data structure. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given an array arr[] and an integer k, count the number of pairs from the array such that the Bitwise XOR of each pair is less than k.
A pair (i, j) is valid if i < j and arr[i] ^ arr[j] < k.
π Examples
Example 1
Input: arr = [1, 2, 3, 5], k = 5
Output: 4
Explanation: Valid pairs with XOR < 5:
1 ^ 2 = 3
1 ^ 3 = 2
1 ^ 5 = 4
2 ^ 3 = 1
Total = 4 pairsExample 2
π Constraints
$1 \le \text{arr.size()}, k \le 5 \times 10^4$
$1 \le \text{arr}[i] \le 5 \times 10^4$
β
My Approach
The optimal solution uses a Binary Trie data structure to efficiently count XOR pairs:
Binary Trie Approach
Trie Structure:
Build a binary trie where each node represents a bit (0 or 1).
Store 32-bit representation of numbers from MSB to LSB.
Each node maintains a count of numbers passing through it.
Query Operation:
For each element, traverse the trie to count existing numbers whose XOR is less than k.
At each bit position, compare bits of current number, k, and trie path.
If k's bit is 1, we can take the path that makes XOR smaller and count those numbers.
If k's bit is 0, we must follow the exact path to keep XOR minimal.
Insertion:
After counting pairs for current element, insert it into the trie.
This ensures we only count each pair once (avoiding duplicates).
Bit Manipulation Logic:
For bit position i: if
k[i] = 1, numbers withXOR[i] = 0are valid (< k).Count all numbers in the matching branch, then explore the opposite branch.
If
k[i] = 0, only exact matching path keeps XOR < k.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n Γ 32) β O(n), where n is the size of the array. Each element requires traversing a fixed-depth trie of 32 levels (for 32-bit integers), making it effectively linear time.
Expected Auxiliary Space Complexity: O(n Γ 32) β O(n), for storing the binary trie structure. In worst case, each number creates 32 new nodes, resulting in linear space proportional to the number of elements.
π§βπ» Code (C++)
β‘ View Alternative Approaches with Code and Analysis
π 2οΈβ£ Hash Map Frequency Approach
π‘ Algorithm Steps:
Use hash map to track XOR frequencies as we iterate.
For each element, check previously seen elements for valid XOR pairs.
Calculate XOR with all previous elements and count those less than k.
Add current element to the frequency map for future iterations.
π Complexity Analysis:
Time: β±οΈ O(nΒ²) - Nested iteration through map for each element
Auxiliary Space: πΎ O(n) - Hash map storage for unique elements
β
Why This Approach?
Simple and intuitive without complex data structures
Easy to implement and debug
Good for small input sizes
Note: This approach results in Time Limit Exceeded (TLE) for large inputs (fails ~1010/1120 test cases due to time constraints).
π 3οΈβ£ Brute Force Nested Loop
π‘ Algorithm Steps:
Use two nested loops to generate all possible pairs.
For each pair (i, j) where i < j, calculate XOR value.
Check if XOR is less than k and increment counter.
Return total count of valid pairs found.
π Complexity Analysis:
Time: β±οΈ O(nΒ²) - All pairs checked explicitly
Auxiliary Space: πΎ O(1) - No extra space needed
β
Why This Approach?
Most straightforward implementation possible
No data structure overhead
Perfect for understanding the problem
Note: This approach results in Time Limit Exceeded (TLE) for large inputs (fails ~1010/1120 test cases due to time constraints).
π 4οΈβ£ Optimized Trie with Path Compression
π‘ Algorithm Steps:
Build trie with 32-bit representation for efficient storage.
Use bit manipulation to traverse optimal paths quickly.
Count valid pairs by exploiting XOR properties in trie structure.
Prune branches early when XOR result exceeds k threshold.
π Complexity Analysis:
Time: β±οΈ O(32n) β O(n) - Fixed depth trie traversal
Auxiliary Space: πΎ O(32n) β O(n) - Trie storage with optimization
β
Why This Approach?
Best time complexity for large datasets
Exploits binary XOR properties efficiently
Industry-standard for XOR range queries
π π Comparison of Approaches
π Approach
β±οΈ Time Complexity
πΎ Space Complexity
β Pros
β οΈ Cons
π³ Trie-Based
π’ O(n)
π‘ O(n)
π Optimal for large n
π§ Complex implementation
πΊοΈ Hash Map
π‘ O(nΒ²)
π‘ O(n)
π Moderate complexity
π Slower for large inputs
π Brute Force
π΄ O(nΒ²)
π’ O(1)
π‘ Simplest to code
π Not scalable
β‘ Optimized Trie
π’ O(n)
π‘ O(n)
β Best performance
π§ Requires bit manipulation
π Best Choice Recommendation
π― Scenario
ποΈ Recommended Approach
π₯ Performance Rating
π Large datasets (n > 10β΅)
π₯ Trie-Based
β β β β β
π Quick implementation
π₯ Hash Map
β β β ββ
π§ Small inputs (n < 100)
π₯ Brute Force
β β β ββ
π― Competitive programming
π Optimized Trie
β β β β β
β Code (Java)
π Code (Python)
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated