📜  数组中两个数字的最大XOR套装2

📅  最后修改于: 2021-04-17 13:25:07             🧑  作者: Mango

给定一个由N个整数组成的数组arr [] ,任务是从给定数组中所有可能的对中找到最大的按位XOR。

例子:

天真的方法:请参阅文章数组中的两个数的最大异或运算,以解决最简单的方法,方法是生成给定数组的所有对,并计算每个对的异或运算,以找出其中的最大值。

时间复杂度: O(N 2 )
辅助空间: O(1)

位屏蔽方法:请参阅文章“数组中两个数的最大XOR”以使用位屏蔽解决问题。

时间复杂度: O(N * log M),其中M是数组中存在最大数字
辅助空间: O(N)

高效的方法:上述方法可以通过使用Trie来解决,方法是将数字的二进制表示形式插入数组arr []中。现在迭代数组arr []中所有元素的二进制表示,如果当前位为0,则在Trie中找到值为1的路径,反之亦然,以获取按位XOR的最大值。更新每个数字的最大值。步骤如下:

  1. maximumXOR初始化为0
  2. 在树的给定数组arr []中插入所有数字的二进制表示形式。在插入Trie时,如果当前位0,则在左侧创建一个节点,否则在当前头部节点的右侧创建一个节点。
  3. 现在,遍历给定的数组,并对每个元素执行以下操作:
    • currentXOR值初始化为0。
    • 遍历当前数字的二进制表示形式。
    • 如果i位1并且node-> left存在,则将currentXOR更新为currentXOR + pow(2,i),并将node更新为node-> left 。其他更新node = node-> right
    • 如果i位为0 ,并且node-> right存在,则将currentXOR更新为currentXOR + pow(2,i),并将node更新为node-> right 。其他更新node = node-> left
  4. 对于上述步骤中的每个数组元素,如果maximumXOR大于currentXOR ,则更新maximumXOR值。
  5. 完成上述步骤后,输出maximumXOR的值。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Structure of Trie
class node {
public:
    node* left;
    node* right;
};
 
// Function to insert binary
// representation of element x
// in the Trie
void insert(int x, node* head)
{
    // Store the head
    node* curr = head;
 
    for (int i = 30; i >= 0; i--) {
 
        // Find the i-th bit
        int val = (x >> i) & 1;
 
        if (val == 0) {
 
            // If curr->left is NULL
            if (!curr->left)
                curr->left = new node();
 
            // Update curr to curr->left
            curr = curr->left;
        }
        else {
 
            // If curr->right is NULL
            if (!curr->right)
                curr->right = new node();
 
            // Update curr to curr->right
            curr = curr->right;
        }
    }
}
 
// Function that finds the maximum
// Bitwise XOR value for all such pairs
int findMaximumXOR(int arr[], int n)
{
    // head Node of Trie
    node* head = new node();
 
    // Insert each element in trie
    for (int i = 0; i < n; i++) {
        insert(arr[i], head);
    }
 
    // Stores the maximum XOR value
    int ans = 0;
 
    // Traverse the given array
    for (int i = 0; i < n; i++) {
 
        // Stores the XOR with current
        // value arr[i]
        int curr_xor = 0;
 
        int M = pow(2, 30);
 
        node* curr = head;
 
        for (int j = 30; j >= 0; j--) {
 
            // Finding ith bit
            int val = (arr[i] >> j) & 1;
 
            // Check if the bit is 0
            if (val == 0) {
 
                // If right node exists
                if (curr->right) {
 
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr->right;
                }
 
                else {
                    curr = curr->left;
                }
            }
 
            else {
 
                // Check if left node exists
                if (curr->left) {
 
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr->left;
                }
                else {
                    curr = curr->right;
                }
            }
 
            // Update M to M/2 for next set bit
            M /= 2;
        }
 
        // Update the maximum XOR
        ans = max(ans, curr_xor);
    }
 
    // Return the maximum XOR found
    return ans;
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 2, 3, 4 };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    cout << findMaximumXOR(arr, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Structure of Trie
static class node
{
    node left;
    node right;
};
 
// Function to insert binary
// representation of element x
// in the Trie
static void insert(int x, node head)
{
     
    // Store the head
    node curr = head;
 
    for(int i = 30; i >= 0; i--)
    {
         
        // Find the i-th bit
        int val = (x >> i) & 1;
 
        if (val == 0)
        {
             
            // If curr.left is null
            if (curr.left == null)
                curr.left = new node();
 
            // Update curr to curr.left
            curr = curr.left;
        }
        else
        {
             
            // If curr.right is null
            if (curr.right == null)
                curr.right = new node();
 
            // Update curr to curr.right
            curr = curr.right;
        }
    }
}
 
// Function that finds the maximum
// Bitwise XOR value for all such pairs
static int findMaximumXOR(int arr[], int n)
{
     
    // head Node of Trie
    node head = new node();
 
    // Insert each element in trie
    for(int i = 0; i < n; i++)
    {
        insert(arr[i], head);
    }
 
    // Stores the maximum XOR value
    int ans = 0;
 
    // Traverse the given array
    for(int i = 0; i < n; i++)
    {
         
        // Stores the XOR with current
        // value arr[i]
        int curr_xor = 0;
 
        int M = (int)Math.pow(2, 30);
 
        node curr = head;
 
        for(int j = 30; j >= 0; j--)
        {
             
            // Finding ith bit
            int val = (arr[i] >> j) & 1;
 
            // Check if the bit is 0
            if (val == 0)
            {
 
                // If right node exists
                if (curr.right != null)
                {
                     
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr.right;
                }
                else
                {
                    curr = curr.left;
                }
            }
 
            else
            {
                 
                // Check if left node exists
                if (curr.left != null)
                {
                     
                    // Update the currentXOR
                    curr_xor += M;
                    curr = curr.left;
                }
                else
                {
                    curr = curr.right;
                }
            }
 
            // Update M to M/2 for next set bit
            M /= 2;
        }
 
        // Update the maximum XOR
        ans = Math.max(ans, curr_xor);
    }
 
    // Return the maximum XOR found
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array arr[]
    int arr[] = { 1, 2, 3, 4 };
 
    int N = arr.length;
 
    // Function call
    System.out.print(findMaximumXOR(arr, N));
}
}
 
// This code is contributed by Amit Katiyar


C#
// C# program for
// the above approach
using System;
class GFG{
 
// Structure of Tree
public class node
{
  public node left;
  public node right;
};
 
// Function to insert binary
// representation of element
// x in the Tree
static void insert(int x,
                   node head)
{
  // Store the head
  node curr = head;
 
  for(int i = 30; i >= 0; i--)
  {
    // Find the i-th bit
    int val = (x >> i) & 1;
 
    if (val == 0)
    {
      // If curr.left is null
      if (curr.left == null)
        curr.left = new node();
 
      // Update curr to curr.left
      curr = curr.left;
    }
    else
    {
      // If curr.right is null
      if (curr.right == null)
        curr.right = new node();
 
      // Update curr to curr.right
      curr = curr.right;
    }
  }
}
 
// Function that finds the maximum
// Bitwise XOR value for all
// such pairs
static int findMaximumXOR(int []arr,
                          int n)
{   
  // Head Node of Tree
  node head = new node();
 
  // Insert each element in tree
  for(int i = 0; i < n; i++)
  {
    insert(arr[i], head);
  }
 
  // Stores the maximum XOR value
  int ans = 0;
 
  // Traverse the given array
  for(int i = 0; i < n; i++)
  {
    // Stores the XOR with
    // current value arr[i]
    int curr_xor = 0;
 
    int M = (int)Math.Pow(2, 30);
    node curr = head;
 
    for(int j = 30; j >= 0; j--)
    {
      // Finding ith bit
      int val = (arr[i] >> j) & 1;
 
      // Check if the bit is 0
      if (val == 0)
      {
        // If right node exists
        if (curr.right != null)
        {
          // Update the currentXOR
          curr_xor += M;
          curr = curr.right;
        }
        else
        {
          curr = curr.left;
        }
      }
 
      else
      {
        // Check if left node exists
        if (curr.left != null)
        {
          // Update the currentXOR
          curr_xor += M;
          curr = curr.left;
        }
        else
        {
          curr = curr.right;
        }
      }
 
      // Update M to M/2
      // for next set bit
      M /= 2;
    }
 
    // Update the maximum XOR
    ans = Math.Max(ans, curr_xor);
  }
 
  // Return the maximum
  // XOR found
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{   
  // Given array []arr
  int []arr = {1, 2, 3, 4};
 
  int N = arr.Length;
 
  // Function call
  Console.Write(findMaximumXOR(arr, N));
}
}
 
// This code is contributed by Rajput-Ji


输出:
7








时间复杂度: O(32 * N)
辅助空间: O(32 * N)