comments | difficulty | edit_url | rating | source | tags | |||
---|---|---|---|---|---|---|---|---|
true |
Hard |
2479 |
Weekly Contest 233 Q4 |
|
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): nums[2] XOR nums[3] = 5
Example 2:
Input: nums = [9,8,4,2,1], low = 5, high = 14 Output: 8 Explanation: All nice pairs (i, j) are as follows: - (0, 2): nums[0] XOR nums[2] = 13 - (0, 3): nums[0] XOR nums[3] = 11 - (0, 4): nums[0] XOR nums[4] = 8 - (1, 2): nums[1] XOR nums[2] = 12 - (1, 3): nums[1] XOR nums[3] = 10 - (1, 4): nums[1] XOR nums[4] = 9 - (2, 3): nums[2] XOR nums[3] = 6 - (2, 4): nums[2] XOR nums[4] = 5
Constraints:
<li><code>1 <= nums.length <= 2 * 10<sup>4</sup></code></li>
<li><code>1 <= nums[i] <= 2 * 10<sup>4</sup></code></li>
<li><code>1 <= low <= high <= 2 * 10<sup>4</sup></code></li>
For this kind of problem that counts the interval
In this problem, we can count how many pairs of numbers have an XOR value less than
Moreover, for array XOR counting problems, we can usually use a "0-1 Trie" to solve them.
The definition of the Trie node is as follows:
children[0]
andchildren[1]
represent the left and right child nodes of the current node, respectively;cnt
represents the number of numbers ending with the current node.
In the Trie, we also define the following two functions:
One function is
Another function is node
of the Trie, traverses the binary bits of node = node.children[v ^ 1]
. Continue to traverse the next bit. If the current binary bit of node = node.children[v]
. Continue to traverse the next bit. After traversing the binary bits of
With the above two functions, we can solve this problem.
We traverse the array nums
. For each number nums
is traversed. Finally, return the answer.
The time complexity is nums
, and nums
. In this problem, we directly take
class Trie:
def __init__(self):
self.children = [None] * 2
self.cnt = 0
def insert(self, x):
node = self
for i in range(15, -1, -1):
v = x >> i & 1
if node.children[v] is None:
node.children[v] = Trie()
node = node.children[v]
node.cnt += 1
def search(self, x, limit):
node = self
ans = 0
for i in range(15, -1, -1):
if node is None:
return ans
v = x >> i & 1
if limit >> i & 1:
if node.children[v]:
ans += node.children[v].cnt
node = node.children[v ^ 1]
else:
node = node.children[v]
return ans
class Solution:
def countPairs(self, nums: List[int], low: int, high: int) -> int:
ans = 0
tree = Trie()
for x in nums:
ans += tree.search(x, high + 1) - tree.search(x, low)
tree.insert(x)
return ans
class Trie {
private Trie[] children = new Trie[2];
private int cnt;
public void insert(int x) {
Trie node = this;
for (int i = 15; i >= 0; --i) {
int v = (x >> i) & 1;
if (node.children[v] == null) {
node.children[v] = new Trie();
}
node = node.children[v];
++node.cnt;
}
}
public int search(int x, int limit) {
Trie node = this;
int ans = 0;
for (int i = 15; i >= 0 && node != null; --i) {
int v = (x >> i) & 1;
if (((limit >> i) & 1) == 1) {
if (node.children[v] != null) {
ans += node.children[v].cnt;
}
node = node.children[v ^ 1];
} else {
node = node.children[v];
}
}
return ans;
}
}
class Solution {
public int countPairs(int[] nums, int low, int high) {
Trie trie = new Trie();
int ans = 0;
for (int x : nums) {
ans += trie.search(x, high + 1) - trie.search(x, low);
trie.insert(x);
}
return ans;
}
}
class Trie {
public:
Trie()
: children(2)
, cnt(0) {}
void insert(int x) {
Trie* node = this;
for (int i = 15; ~i; --i) {
int v = x >> i & 1;
if (!node->children[v]) {
node->children[v] = new Trie();
}
node = node->children[v];
++node->cnt;
}
}
int search(int x, int limit) {
Trie* node = this;
int ans = 0;
for (int i = 15; ~i && node; --i) {
int v = x >> i & 1;
if (limit >> i & 1) {
if (node->children[v]) {
ans += node->children[v]->cnt;
}
node = node->children[v ^ 1];
} else {
node = node->children[v];
}
}
return ans;
}
private:
vector<Trie*> children;
int cnt;
};
class Solution {
public:
int countPairs(vector<int>& nums, int low, int high) {
Trie* tree = new Trie();
int ans = 0;
for (int& x : nums) {
ans += tree->search(x, high + 1) - tree->search(x, low);
tree->insert(x);
}
return ans;
}
};
type Trie struct {
children [2]*Trie
cnt int
}
func newTrie() *Trie {
return &Trie{}
}
func (this *Trie) insert(x int) {
node := this
for i := 15; i >= 0; i-- {
v := (x >> i) & 1
if node.children[v] == nil {
node.children[v] = newTrie()
}
node = node.children[v]
node.cnt++
}
}
func (this *Trie) search(x, limit int) (ans int) {
node := this
for i := 15; i >= 0 && node != nil; i-- {
v := (x >> i) & 1
if (limit >> i & 1) == 1 {
if node.children[v] != nil {
ans += node.children[v].cnt
}
node = node.children[v^1]
} else {
node = node.children[v]
}
}
return
}
func countPairs(nums []int, low int, high int) (ans int) {
tree := newTrie()
for _, x := range nums {
ans += tree.search(x, high+1) - tree.search(x, low)
tree.insert(x)
}
return
}