给定由N个非负整数组成的数组arr []和由{X,M}类型的查询组成的2D数组query [] [] ,每个查询的任务是找到X的最大按位异或值最大为M的数组元素。如果找不到按位异或,则打印“ -1” 。
例子:
Input: arr[] = {0, 1, 2, 3, 4}, queries[][] = {{3, 1}, {1, 3}, {5, 6}}
Output: {3, 3, 7}
Explanation:
Query 1: The query is {3, 1}. Maximum Bitwise XOR = 3 ^ 0 = 3.
Query 2: The query is {1, 3}. Maximum Bitwise XOR = 1 ^ 2 = 3.
Query 3: The query is {5, 6}. Maximum Bitwise XOR = 5 ^ 2 = 7.
Input: arr[] = {5, 2, 4, 6, 6, 3}, queries[][] = {{12, 4}, {8, 1}, {6, 3}}
Output: {15, -1, 5}
天真的方法:解决给定问题的最简单方法是遍历每个查询{X,M}的给定数组,并使用一个值最大为M的数组元素打印X的按位XOR的最大值。如果不存在小于M的值,则为查询打印“ -1” 。
时间复杂度: O(N * Q)
辅助空间: O(1)
高效方法:还可以通过使用Trie数据结构来存储值最大为M的所有元素来优化上述方法。因此,问题减少到找到数组中两个元素的最大XOR。请按照以下步骤解决问题:
- 初始化一个变量,例如index ,以遍历数组。
- 初始化一个数组,例如ans [] ,该数组存储每个查询的结果。
- 初始化一个辅助数组,例如temp [] [3] ,并将所有查询与每个查询的索引一起存储在其中。
- 根据第二个参数,即temp [1] (= M ),对给定的数组temp []进行排序。
- 以升序对给定数组arr []进行排序。
- 遍历数组temp [] ,对于每个查询{X,M,idx} ,执行以下步骤:
- 迭代直到index的值小于N并且arr [index]最多为M。如果发现为真,则将该节点插入为N的二进制表示形式,并递增index 。
- 完成上述步骤后,如果index的值不为零,则在Trie(表示result )中找到值为X的节点,并将当前查询的最大值更新为result 。否则,将当前查询的最大值更新为“ -1” 。
- 完成上述步骤后,将数组ans []打印为每个查询的结果最大值。
下面是上述方法的实现:
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
// Trie Node Class
class TrieNode {
TrieNode nums[] = new TrieNode[2];
int prefixValue;
}
class sol {
// Function to find the maximum XOR
// of X with any array element <= M
// for each query of the type {X, M}
public void maximizeXor(
int[] nums, int[][] queries)
{
int queriesLength = queries.length;
int[] ans = new int[queriesLength];
int[][] temp = new int[queriesLength][3];
// Stores the queries
for (int i = 0; i < queriesLength; i++) {
temp[i][0] = queries[i][0];
temp[i][1] = queries[i][1];
temp[i][2] = i;
}
// Sort the query
Arrays.sort(temp,
(a, b) -> {
return a[1]
- b[1];
});
int index = 0;
// Sort the array
Arrays.sort(nums);
TrieNode root = new TrieNode();
// Traverse the given query
for (int query[] : temp) {
// Traverse the array nums[]
while (index < nums.length
&& nums[index]
<= query[1]) {
// Insert the node into the Trie
insert(root, nums[index]);
index++;
}
// Stores the resultant
// maximum value
int tempAns = -1;
// Find the maximum value
if (index != 0) {
// Search the node in the Trie
tempAns = search(root,
query[0]);
}
// Update the result
// for each query
ans[query[2]] = tempAns;
}
// Print the answer
for (int num : ans) {
System.out.print(num + " ");
}
}
// Function to insert the
// root in the trieNode
public void insert(TrieNode root,
int n)
{
TrieNode node = root;
// Iterate from 31 to 0
for (int i = 31; i >= 0; i--) {
// Find the bit at i-th position
int bit = (n >> i) & 1;
if (node.nums[bit] == null) {
node.nums[bit]
= new TrieNode();
}
node = node.nums[bit];
}
// Update the value
node.prefixValue = n;
}
// Function to search the root
// with the value and perform
// the Bitwise XOR with N
public int search(TrieNode root,
int n)
{
TrieNode node = root;
// Iterate from 31 to 0
for (int i = 31; i >= 0; i--) {
// Find the bit at ith
// position
int bit = (n >> i) & 1;
int requiredBit = bit
== 1
? 0
: 1;
if (node.nums[requiredBit]
!= null) {
node = node.nums[requiredBit];
}
else {
node = node.nums[bit];
}
}
// Return the prefixvalue XORed
// with N
return node.prefixValue ^ n;
}
}
class GFG {
// Driver Code
public static void main(String[] args)
{
sol tt = new sol();
int[] nums = { 0, 1, 2, 3, 4 };
int[][] queries = { { 3, 1 },
{ 1, 3 },
{ 5, 6 } };
tt.maximizeXor(nums, queries);
}
}
3 3 7
时间复杂度: O(N * log N + K * log K)
辅助空间: O(N)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。