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

📅  最后修改于: 2021-09-06 06:32:58             🧑  作者: Mango

给定一个由N 个非负整数组成的数组arr[]和一个由{X, M}类型的查询组成的二维数组queries[][] ,每个查询的任务是找到X与任何其值至多为M 的数组元素。如果无法找到按位异或,则打印“-1”

例子:

朴素方法:解决给定问题的最简单方法是为每个查询{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