|
| 1 | +# [1803. Count Pairs With XOR in a Range (Hard)](https://leetcode.com/problems/count-pairs-with-xor-in-a-range/) |
| 2 | + |
| 3 | +<p>Given a <strong>(0-indexed)</strong> integer array <code>nums</code> and two integers <code>low</code> and <code>high</code>, return <em>the number of <strong>nice pairs</strong></em>.</p> |
| 4 | + |
| 5 | +<p>A <strong>nice pair</strong> is a pair <code>(i, j)</code> where <code>0 <= i < j < nums.length</code> and <code>low <= (nums[i] XOR nums[j]) <= high</code>.</p> |
| 6 | + |
| 7 | +<p> </p> |
| 8 | +<p><strong>Example 1:</strong></p> |
| 9 | + |
| 10 | +<pre><strong>Input:</strong> nums = [1,4,2,7], low = 2, high = 6 |
| 11 | +<strong>Output:</strong> 6 |
| 12 | +<strong>Explanation:</strong> All nice pairs (i, j) are as follows: |
| 13 | + - (0, 1): nums[0] XOR nums[1] = 5 |
| 14 | + - (0, 2): nums[0] XOR nums[2] = 3 |
| 15 | + - (0, 3): nums[0] XOR nums[3] = 6 |
| 16 | + - (1, 2): nums[1] XOR nums[2] = 6 |
| 17 | + - (1, 3): nums[1] XOR nums[3] = 3 |
| 18 | + - (2, 3): nums[2] XOR nums[3] = 5 |
| 19 | +</pre> |
| 20 | + |
| 21 | +<p><strong>Example 2:</strong></p> |
| 22 | + |
| 23 | +<pre><strong>Input:</strong> nums = [9,8,4,2,1], low = 5, high = 14 |
| 24 | +<strong>Output:</strong> 8 |
| 25 | +<strong>Explanation:</strong> All nice pairs (i, j) are as follows: |
| 26 | + - (0, 2): nums[0] XOR nums[2] = 13 |
| 27 | + - (0, 3): nums[0] XOR nums[3] = 11 |
| 28 | + - (0, 4): nums[0] XOR nums[4] = 8 |
| 29 | + - (1, 2): nums[1] XOR nums[2] = 12 |
| 30 | + - (1, 3): nums[1] XOR nums[3] = 10 |
| 31 | + - (1, 4): nums[1] XOR nums[4] = 9 |
| 32 | + - (2, 3): nums[2] XOR nums[3] = 6 |
| 33 | + - (2, 4): nums[2] XOR nums[4] = 5</pre> |
| 34 | + |
| 35 | +<p> </p> |
| 36 | +<p><strong>Constraints:</strong></p> |
| 37 | + |
| 38 | +<ul> |
| 39 | + <li><code>1 <= nums.length <= 2 * 10<sup>4</sup></code></li> |
| 40 | + <li><code>1 <= nums[i] <= 2 * 10<sup>4</sup></code></li> |
| 41 | + <li><code>1 <= low <= high <= 2 * 10<sup>4</sup></code></li> |
| 42 | +</ul> |
| 43 | + |
| 44 | + |
| 45 | +**Related Topics**: |
| 46 | +[Trie](https://leetcode.com/tag/trie/) |
| 47 | + |
| 48 | +## Solution 1. Trie |
| 49 | + |
| 50 | +### Complexity Analysis |
| 51 | + |
| 52 | +Adding a number into trie takes `O(16) = O(1)` time. |
| 53 | + |
| 54 | +The `count` will at most visit a perfect binary-tree like trie whose height is `16`, so there are at most `O(2^16-1) = O(1)` nodes. Hence the space complexity is `O(1)`. |
| 55 | + |
| 56 | +Since we repeat the above operations `N` times, the overall time complexity is `O(N)`. |
| 57 | + |
| 58 | +```cpp |
| 59 | +// OJ: https://leetcode.com/problems/count-pairs-with-xor-in-a-range/ |
| 60 | +// Author: github.com/lzl124631x |
| 61 | +// Time: O(N) |
| 62 | +// Space: O(1) |
| 63 | +struct TrieNode { |
| 64 | + TrieNode *next[2] = {}; |
| 65 | + int cnt = 0; |
| 66 | +}; |
| 67 | +class Solution { |
| 68 | + void add(TrieNode *node, int n) { |
| 69 | + for (int i = 15; i >= 0; --i) { |
| 70 | + int b = n >> i & 1; |
| 71 | + if (node->next[b] == NULL) node->next[b] = new TrieNode(); |
| 72 | + node = node->next[b]; |
| 73 | + node->cnt++; |
| 74 | + } |
| 75 | + } |
| 76 | + int count(TrieNode *node, int i, int n, int rl, int rh, int low, int high) { |
| 77 | + if (rl >= low && rh <= high) return node->cnt; |
| 78 | + if (rh < low || rl > high) return 0; |
| 79 | + int b = n >> i & 1, r = b ^ 1, mask = ~(1 << i); |
| 80 | + return (node->next[0] ? count(node->next[0], i - 1, n, rl & mask | (b << i), rh & mask | (b << i), low, high) : 0) |
| 81 | + + (node->next[1] ? count(node->next[1], i - 1, n, rl & mask | (r << i), rh & mask | (r << i), low, high) : 0); |
| 82 | + } |
| 83 | +public: |
| 84 | + int countPairs(vector<int>& A, int low, int high) { |
| 85 | + TrieNode root; |
| 86 | + int ans = 0; |
| 87 | + for (int n : A) { |
| 88 | + ans += count(&root, 15, n, 0, (1 << 16) - 1, low, high); |
| 89 | + add(&root, n); |
| 90 | + } |
| 91 | + return ans; |
| 92 | + } |
| 93 | +}; |
| 94 | +``` |
0 commit comments