Count Pairs With XOR in a Range - Complete Solution Guide
Count Pairs With XOR in a Range is LeetCode problem 1803, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given a (0-indexed) integer array nums and two integers low and high , return the number of nice pairs . A nice pair is a pair (i, j) where 0 <= i < j < nums.length and low <= (nums[i] XOR nums[j]) <= high . Example 1: Input: nums = [1,4,2,7], low = 2, high = 6 Output: 6 Explanation: All nice pairs (i, j) are as follows: - (0, 1): nums[0] XOR nums[1] = 5 - (0, 2): nums[0] XOR nums[2] = 3 - (0, 3): nums[0] XOR nums[3] = 6 - (1, 2): nums[1] XOR nums[2] = 6 - (1, 3): nums[1] XOR nums[3] = 3 - (2, 3
Detailed Explanation
The problem asks us to find the number of pairs (i, j) in a given integer array `nums` such that 0 <= i < j < nums.length and `low` <= (nums[i] XOR nums[j]) <= `high`. In other words, we need to count how many pairs of elements in the array have an XOR value that falls within the specified range [low, high].
Solution Approach
The solution uses a Trie (prefix tree) to store the binary representations of the numbers in the array. The core idea is to use the Trie to efficiently count the number of pairs whose XOR value is less than a given value `k`. The `countPairs` function computes the result by calling a helper function `count_less_than(k)` twice: once for `high + 1` and once for `low`, and then returns the difference. The `count_less_than(k)` function iterates through the `nums` array, inserting each number into the Trie and, at the same time, querying the Trie to count the number of existing numbers that, when XORed with the current number, result in a value less than `k`.
Step-by-Step Algorithm
- Step 1: Define a Trie data structure with a `count` field to keep track of how many numbers share that prefix.
- Step 2: Implement the `count_less_than(k)` function. This function initializes an empty Trie.
- Step 3: Iterate through the `nums` array. For each number `num`:
- Step 4: Initialize a `node` pointer to the root of the Trie and a `current_count` to 0.
- Step 5: Iterate from the most significant bit (MAX_BIT = 14) to the least significant bit (0).
- Step 6: Extract the `num_bit` (the i-th bit of `num`) and the `k_bit` (the i-th bit of `k`).
- Step 7: If `k_bit` is 1, this means that to have an XOR value less than `k`, we can have either a 0 or 1 in the XOR result. If the number present in the Trie have the same bit as num (num_bit), the XOR will be '0'. Then we add all the node count to the current count
- Step 8: If `k_bit` is 0, this means the XOR result must also be '0'.
- Step 9: Update total_pairs by adding current_count
- Step 10: Insert the number `num` into the Trie. Traverse the Trie based on the bits of `num`, incrementing the `count` at each node.
- Step 11: Return the `total_pairs`.
- Step 12: Calculate and return the final result: `count_less_than(high + 1) - count_less_than(low)`.
Key Insights
- Insight 1: The problem can be solved efficiently using a Trie data structure to store the numbers in their binary representation.
- Insight 2: We can break the range [low, high] into two subproblems: count pairs with XOR less than or equal to `high` and count pairs with XOR less than `low`. The desired result is the difference between these two counts.
- Insight 3: To handle the constraints, the maximum number of bits needed to represent each number is determined (15 bits, since 2 * 10^4 < 2^15). This defines the depth of the Trie.
Complexity Analysis
Time Complexity: O(n*log(m))
Space Complexity: O(n*log(m))
Topics
This problem involves: Array, Bit Manipulation, Trie.
Companies
Asked at: Vimeo.