给定一个大小为N的数组arr[]和一个整数K ,任务是计算给定数组中对的数量,使得每对的按位异或大于K 。
例子:
Input: arr = {1, 2, 3, 5} , K = 2
Output: 4
Explanation:
Bitwise XOR of all possible pairs that satisfy the given conditions are:
arr[0] ^ arr[1] = 1 ^ 2 = 3
arr[0] ^ arr[3] = 1 ^ 5 = 4
arr[1] ^ arr[3] = 2 ^ 5 = 7
arr[0] ^ arr[3] = 3 ^ 5 = 6
Therefore, the required output is 4.
Input: arr[] = {3, 5, 6,8}, K = 2
Output: 6
朴素方法:解决这个问题最简单的方法是遍历给定数组并生成给定数组的所有可能对,对于每一对,检查该对的按位异或是否大于K。如果发现为真,则增加按位异或大于K的对的计数。最后,打印获得的此类对的计数。
时间复杂度:O(N 2 )
辅助空间: O(1)
有效的方法:可以使用 Trie 解决问题。这个想法是迭代给定的数组,对于每个数组元素,计算Trie 中与当前元素按位异或大于K的元素的数量,并将当前元素的二进制表示插入到Trie 中。最后,打印按位异或大于K的对的计数。请按照以下步骤解决问题:
- 创建一个具有根节点的 Trie,比如root来存储给定数组的每个元素的二进制表示。
- 遍历给定数组,计算Trie中与当前元素按位异或大于K的元素个数,插入当前元素的二进制表示。
- 最后,打印满足给定条件的对的计数。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Structure of Trie
struct TrieNode
{
// Stores binary represention
// of numbers
TrieNode *child[2];
// Stores count of elements
// present in a node
int cnt;
// Function to initialize
// a Trie Node
TrieNode() {
child[0] = child[1] = NULL;
cnt = 0;
}
};
// Function to insert a number into Trie
void insertTrie(TrieNode *root, int N) {
// Traverse binary representation of X.
for (int i = 31; i >= 0; i--) {
// Stores ith bit of N
bool x = (N) & (1 << i);
// Check if an element already
// present in Trie having ith bit x.
if(!root->child[x]) {
// Create a new node of Trie.
root->child[x] = new TrieNode();
}
// Update count of elements
// whose ith bit is x
root->child[x]->cnt+= 1;
// Update root.
root= root->child[x];
}
}
// Function to count elements
// in Trie whose XOR with N
// exceeds K
int cntGreater(TrieNode * root,
int N, int K)
{
// Stores count of elements
// whose XOR with N exceeding K
int cntPairs = 0;
// Traverse binary representation
// of N and K in Trie
for (int i = 31; i >= 0 &&
root; i--) {
// Stores ith bit of N
bool x = N & (1 << i);
// Stores ith bit of K
bool y = K & (1 << i);
// If the ith bit of K is 1
if (y) {
// Update root.
root =
root->child[1 - x];
}
// If the ith bit of K is 0
else{
// If an element already
// present in Trie having
// ith bit (1 - x)
if (root->child[1 - x]) {
// Update cntPairs
cntPairs +=
root->child[1 - x]->cnt;
}
// Update root.
root = root->child[x];
}
}
return cntPairs;
}
// Function to count pairs that
// satisfy the given conditions.
int cntGreaterPairs(int arr[], int N,
int K) {
// Create root node of Trie
TrieNode *root = new TrieNode();
// Stores count of pairs that
// satisfy the given conditions
int cntPairs = 0;
// Traverse the given array.
for(int i = 0;i < N; i++){
// Update cntPairs
cntPairs += cntGreater(root,
arr[i], K);
// Insert arr[i] into Trie.
insertTrie(root, arr[i]);
}
return cntPairs;
}
//Driver code
int main()
{
int arr[] = {3, 5, 6, 8};
int K= 2;
int N = sizeof(arr) / sizeof(arr[0]);
cout<
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Structure of Trie
static class TrieNode
{
// Stores binary represention
// of numbers
TrieNode []child = new TrieNode[2];
// Stores count of elements
// present in a node
int cnt;
// Function to initialize
// a Trie Node
TrieNode()
{
child[0] = child[1] = null;
cnt = 0;
}
};
// Function to insert a number
// into Trie
static void insertTrie(TrieNode root,
int N)
{
// Traverse binary representation
// of X.
for (int i = 31; i >= 0; i--)
{
// Stores ith bit of N
int x = (N) & (1 << i);
// Check if an element already
// present in Trie having ith
// bit x.
if (x < 2 && root.child[x] == null)
{
// Create a new node of Trie.
root.child[x] = new TrieNode();
}
// Update count of elements
// whose ith bit is x
if(x < 2 && root.child[x] != null)
root.child[x].cnt += 1;
// Update root.
if(x < 2)
root = root.child[x];
}
}
// Function to count elements
// in Trie whose XOR with N
// exceeds K
static int cntGreater(TrieNode root,
int N, int K)
{
// Stores count of elements
// whose XOR with N exceeding K
int cntPairs = 1;
// Traverse binary representation
// of N and K in Trie
for (int i = 31; i >= 0 &&
root!=null; i--)
{
// Stores ith bit of N
int x = N & (1 << i);
// Stores ith bit of K
int y = K & (1 << i);
// If the ith bit of K is 1
if (y == 1)
{
// Update root.
root = root.child[1 - x];
}
// If the ith bit of K is 0
else
{
// If an element already
// present in Trie having
// ith bit (1 - x)
if (x < 2 &&
root.child[1 - x] != null)
{
// Update cntPairs
cntPairs += root.child[1 - x].cnt;
}
// Update root.
if(x < 2)
root = root.child[x];
}
}
return cntPairs;
}
// Function to count pairs that
// satisfy the given conditions.
static int cntGreaterPairs(int arr[],
int N, int K)
{
// Create root node of Trie
TrieNode root = new TrieNode();
// Stores count of pairs that
// satisfy the given conditions
int cntPairs = 0;
// Traverse the given array.
for (int i = 0; i < N; i++)
{
// Update cntPairs
cntPairs += cntGreater(root,
arr[i], K);
// Insert arr[i] into Trie.
insertTrie(root, arr[i]);
}
return cntPairs;
}
// Driver code
public static void main(String[] args)
{
int arr[] = {3, 5, 6, 8};
int K = 2;
int N = arr.length;
System.out.print(cntGreaterPairs(arr,
N, K));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program to implement
# the above approach
# Structure of Trie
class TrieNode:
# Function to initialize
# a Trie Node
def __init__(self):
self.child = [None, None]
self.cnt = 0
# Function to insert a number into Trie
def insertTrie(root, N):
# Traverse binary representation of X.
for i in range(31, -1, -1):
# Stores ith bit of N
x = bool((N) & (1 << i))
# Check if an element already
# present in Trie having ith bit x.
if (root.child[x] == None):
# Create a new node of Trie.
root.child[x] = TrieNode()
# Update count of elements
# whose ith bit is x
root.child[x].cnt += 1
# Update root
root= root.child[x]
# Function to count elements
# in Trie whose XOR with N
# exceeds K
def cntGreater(root, N, K):
# Stores count of elements
# whose XOR with N exceeding K
cntPairs = 0
# Traverse binary representation
# of N and K in Trie
for i in range(31, -1, -1):
if (root == None):
break
# Stores ith bit of N
x = bool(N & (1 << i))
# Stores ith bit of K
y = K & (1 << i)
# If the ith bit of K is 1
if (y != 0):
# Update root
root = root.child[1 - x]
# If the ith bit of K is 0
else:
# If an element already
# present in Trie having
# ith bit (1 - x)
if (root.child[1 - x]):
# Update cntPairs
cntPairs += root.child[1 - x].cnt
# Update root
root = root.child[x]
return cntPairs
# Function to count pairs that
# satisfy the given conditions.
def cntGreaterPairs(arr, N, K):
# Create root node of Trie
root = TrieNode()
# Stores count of pairs that
# satisfy the given conditions
cntPairs = 0
# Traverse the given array.
for i in range(N):
# Update cntPairs
cntPairs += cntGreater(root, arr[i], K)
# Insert arr[i] into Trie.
insertTrie(root, arr[i])
return cntPairs
# Driver code
if __name__=='__main__':
arr = [ 3, 5, 6, 8 ]
K = 2
N = len(arr)
print(cntGreaterPairs(arr, N, K))
# This code is contributed by rutvik_56
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Structure of Trie
public class TrieNode
{
// Stores binary represention
// of numbers
public TrieNode []child = new TrieNode[2];
// Stores count of elements
// present in a node
public int cnt;
// Function to initialize
// a Trie Node
public TrieNode()
{
child[0] = child[1] = null;
cnt = 0;
}
};
// Function to insert a number
// into Trie
static void insertTrie(TrieNode root,
int N)
{
// Traverse binary representation
// of X.
for(int i = 31; i >= 0; i--)
{
// Stores ith bit of N
int x = (N) & (1 << i);
// Check if an element already
// present in Trie having ith
// bit x.
if (x < 2 && root.child[x] == null)
{
// Create a new node of Trie.
root.child[x] = new TrieNode();
}
// Update count of elements
// whose ith bit is x
if(x < 2 && root.child[x] != null)
root.child[x].cnt += 1;
// Update root.
if(x < 2)
root = root.child[x];
}
}
// Function to count elements
// in Trie whose XOR with N
// exceeds K
static int cntGreater(TrieNode root,
int N, int K)
{
// Stores count of elements
// whose XOR with N exceeding K
int cntPairs = 1;
// Traverse binary representation
// of N and K in Trie
for(int i = 31; i >= 0 &&
root != null; i--)
{
// Stores ith bit of N
int x = N & (1 << i);
// Stores ith bit of K
int y = K & (1 << i);
// If the ith bit of K is 1
if (y == 1)
{
// Update root.
root = root.child[1 - x];
}
// If the ith bit of K is 0
else
{
// If an element already
// present in Trie having
// ith bit (1 - x)
if (x < 2 &&
root.child[1 - x] != null)
{
// Update cntPairs
cntPairs += root.child[1 - x].cnt;
}
// Update root.
if(x < 2)
root = root.child[x];
}
}
return cntPairs;
}
// Function to count pairs that
// satisfy the given conditions.
static int cntGreaterPairs(int []arr,
int N, int K)
{
// Create root node of Trie
TrieNode root = new TrieNode();
// Stores count of pairs that
// satisfy the given conditions
int cntPairs = 0;
// Traverse the given array.
for(int i = 0; i < N; i++)
{
// Update cntPairs
cntPairs += cntGreater(root,
arr[i], K);
// Insert arr[i] into Trie.
insertTrie(root, arr[i]);
}
return cntPairs;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 3, 5, 6, 8 };
int K = 2;
int N = arr.Length;
Console.Write(cntGreaterPairs(arr,
N, K));
}
}
// This code is contributed by gauravrajput1
6
时间复杂度:O(N * 32)
辅助空间: O(N * 32)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live