给定一个由N 个非负整数组成的数组arr[]和一个由{X, M}类型的查询组成的二维数组queries[][] ,每个查询的任务是找到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}遍历给定数组,并打印X与值最大为M的数组元素的按位异或的最大值。如果不存在任何小于M 的值,则为查询打印“-1” 。
时间复杂度: O(N*Q)
辅助空间: O(1)
高效的方法:上述方法也可以通过使用 Trie 数据结构来存储所有具有至多 M值的元素来优化。因此,问题简化为找出数组中两个元素的最大异或。请按照以下步骤解决问题:
- 初始化一个变量,比如index ,以遍历数组。
- 初始化一个数组,比如ans[] ,它存储每个查询的结果。
- 初始化一个辅助数组,比如temp[][3] ,并将所有查询与每个查询的索引一起存储在其中。
- 根据第二个参数对给定的数组temp[]进行排序,即temp[1] (= M )。
- 按升序对给定的数组arr[]进行排序。
- 遍历数组temp[]并对每个查询{X, M, idx}执行以下步骤:
- 迭代直到index的值小于N并且arr[index]至多为M或不为M。如果发现为真,则将该节点作为N的二进制表示插入并递增index 。
- 完成上述步骤后,如果index的值为非零,则在 Trie 中找到值为X的节点(比如result ),并将当前查询的最大值更新为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 Classes Live