Problem Statement
Given two integer arrays A[] and B[] of size N and M respectively. The task is to count the number of pairs (x, y) such that x^y > y^x, where x is an element of array A[], while y is an element of array B[].
Examples:
Input: A[] = {2, 1, 6}, B[] = {1, 5}
Output: 3
Explanation:
There are three possible pairs :
- (2, 1) : 2 ^ 1 > 1 ^ 2
- (6, 1) : 6 ^ 1 > 1 ^ 6
- (2, 5) : 2 ^ 5 > 5 ^ 2
Input: A[] = {1, 2, 3}, B[] = {4, 5, 6, 7};
Output: 7
Brute Force Approach
The simplest approach is to run two nested loops over the arrays A[] and B[] and if any of the pairs satisfy the above condition, increment the count.
C++ Implementation of Brute Force Approach
int countPairs(int A[], int B[], int N, int M)
{
int count = 0;
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
if (pow(A[i], B[j]) > pow(B[j], A[i])){
count++;
}
}
}
return ans;
}
Java Implementation of Brute Force Approach
countPairs(int[] A, int[] B, int N, int M)
{
int count = 0;
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
if (Math.pow(A[i], B[j]) > Math.pow(B[j], A[i])){
count++;
}
}
}
return ans;
}
Python Implementation of Brute Force Approach
def countPairs(A, B, N, M)
{
count = 0;
for i in range(N):
for j in range(M):
if (A[i]**B[j] > B[j]**A[i])){
count = count + 1;
return ans;
}
Time Complexity: O(N * M) where N and M are the size of the A[] and B[].
Space Complexity: O(1), as no extra space is used.
Efficient Approach (Using binary search)
The trick to solving this problem is based on the fact that, for a pair (X, Y), if Y > X,
then X ^ Y > Y ^ X.
There are a few exceptions, for which this condition fails.
- If X = 0, then RHS is always 1 i.e. 0 ^ Y < Y ^ 0, hence the count for this case is 0.
- If X = 1, then total pairs is equal to the number of 0’s in the array B[]. This is based on the fact that 1 ^ 0 > 0 ^ 1, but 0 < 1.
- If X = 2. but Y = 3 or Y = 4, the condition fails, as 2 ^ 3 < 3 ^3. Similarly, 2 ^ 4 == 4 ^2
If X = 3, but Y = 2, we need to consider it since, 3 ^ 2 > 2 ^3 but 2 < 3.
The exceptions can be shown in tabular format as follows:
Algorithm
- Sort the array B[].
- Consider a frequency array to count the frequency of 0, 1, 2, 3, 4 in array B[].
- For every ith element of A[], find the index, idx of the smallest element greater than A[i] in B[] using binary search.
- To handle the exceptions, follow the below approach:
- If, A[i] = 0, count = 0
- If, A[i] = 1, count = freq[1] in B[].
- If, A[i] = 2, decrement count by frequency of 3 and 4 in B[].
- If, A[i] = 3, increment count by frequency of 2 in B[].
- All the integers, after index idx satisfies the above condition, hence count should be incremented by N – idx.
- Return count.
C++ Code
int count(int x, int B[], int N, int freq[])
{
if (x == 0)
return 0;
if (x == 1)
return freq[0];
int* idx = upper_bound(B, B + M, x);
int countx = (B + M) - idx;
countx += (freq[0] + freq[1]);
if (x == 2)
countx -= (freq[3] + freq[4]);
if (x == 3)
countx += freq[2];
return countx;
}
int countPairs(int A[], int B[], int N, int M)
{
int freq[5] = { 0 };
for (int i = 0; i < M; i++)
if (B[i] < 5)
freq[Y[i]]++;
sort(B, B + M);
int total_pairs = 0;
for (int i = 0; i < N; i++)
total_pairs += count(A[i], B, M, freq);
return total_pairs;
}
Java Code
count(int x, int B[], int M, int freq[]){
if (x == 0)
return 0;
if (x == 1)
return freq[0];
int idx = Arrays.binarySearch(B, x);
int countx = 0;
if (idx < 0) {
idx = Math.abs(idx + 1);
countx = Y.length - idx;
}
else {
while (idx < n && Y[idx] == x) {
idx++;
}
countx = M - idx;
}
countx += (freq[0] + freq[1]);
if (x == 2)
countx -= (freq[3] + freq[4]);
if (x == 3)
countx += freq[2];
return countx;
}
countPairs(int A[], int B[], int N, int M)
{
int freq[] = new int[5];
for (int i = 0; i < M; i++)
if (B[i] < 5)
freq[Y[i]]++;
Arrays.sort(B);
long total_pairs = 0;
for (int i = 0; i < N; i++)
total_pairs += count(A[i], B, M, freq);
return total_pairs;
}
Python Code
import bisect
def count(x, B , n, freq):
if x == 0:
return 0
if x == 1:
return freq[0]
idx = bisect.bisect_right(B, x)
countx = n - idx
ans += freq[0] + freq[1]
if x == 2:
countx -= freq[3] + freq[4]
if x == 3:
countx += freq[2]
return ans
def count_pairs(A, B, N, M):
freq = [0] * 5
for i in range(M):
if B[i] < 5:
freq[B[i]] += 1
B.sort()
total_pairs = 0
for x in A:
total_pairs += count(x, B, M, freq)
return total_pairs
Time Complexity: O(N * log N + M * log M), where N and M are the size of the A[] and B[].Space Complexity: O(1)
Practice Questions
Pairs With Given XOR
Pair With Given Difference
Frequently Asked Questions
What is the time complexity of the above approach?
The time complexity is O(NlogN + MlogM), where N and M are the size of arrays A[] and B[] respectively.
Why do you need to sort the array B[]?
Since we are applying binary search on array B, to count the smallest index greater than A[i], and binary search works on sorted arrays, we need to sort array B[].
