📌  相关文章
📜  查询以任何不超过M的数组元素计算X的最大按位XOR

📅  最后修改于: 2021-04-17 17:41:05             🧑  作者: Mango

给定由N个非负整数组成的数组arr []和由{X,M}类型的查询组成的2D数组query [] [] ,每个查询的任务是找到X的最大按位异或值最大为M的数组元素。如果找不到按位异或,则打印“ -1”

例子:

天真的方法:解决给定问题的最简单方法是遍历每个查询{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)