1. Problem Statement
Given an even-sized integer array, divide it into two equal halves.
A pair of indices (i, j) is called a dominant pair if:
ibelongs to the first half.jbelongs to the second half.arr[i] >= 5 * arr[j]
We need to count the total number of dominant pairs.
Example
arr = [10, 2, 2, 1]
The array is divided into:
First half: [10, 2]
Second half: [2, 1]
Now check the possible pairs:
10 >= 5 * 2
10 >= 5 * 1
So there are 2 dominant pairs.
Therefore:
Output = 2
2. Understanding the Important Observation
Suppose we have:
First half: [10, 8, 2]
Second half: [1, 1, 2]
We need to count pairs satisfying:
firstElement >= 5 * secondElement
A brute-force solution would compare every element from the first half with every element from the second half.
For n elements, each half contains n/2 elements.
Therefore, brute force takes:
O(n²)
But the expected complexity is:
O(n log n)
So we need something better.
The key idea is:
Sort both halves and use two pointers.
3. Why Sorting Helps
Consider:
First half: [10, 8, 2]
Second half: [1, 1, 2]
Sort both halves:
First half: [2, 8, 10]
Second half: [1, 1, 2]
Now consider 8.
We need:
8 >= 5 * secondElement
Therefore:
secondElement <= 8 / 5
The elements 1 and 1 satisfy the condition.
So 8 gives us 2 dominant pairs.
Now consider 10:
10 >= 5 * 1
10 >= 5 * 1
10 >= 5 * 2
All three elements satisfy the condition.
So 10 gives us 3 pairs.
Total:
2 + 3 = 5
4. Two-Pointer Technique
After sorting:
First half: [2, 8, 10]
Second half: [1, 1, 2]
We maintain a pointer j for the second half.
Initially:
j = half
For every element in the first half, move j while:
arr[i] >= 5 * arr[j]
Every element before j is a valid partner.
For example, when:
arr[i] = 8
we check:
8 >= 5 * 1 → true
8 >= 5 * 1 → true
8 >= 5 * 2 → false
Therefore, there are:
2
valid elements in the second half.
5. Why Doesn't
j Move Backward?This is the most important part of the solution.
Both halves are sorted.
Suppose 8 can form dominant pairs with:
1, 1
Now we move to 10.
Because:
10 >= 8
anything that was valid for 8 will also be valid for 10.
Therefore, there is no need to move j backward.
This makes the two-pointer approach efficient.
6. Java Implementation
import java.util.*;
class Solution {
public int dominantPairs(int[] arr) {
int n = arr.length;
int half = n / 2;
// Sort the first half
Arrays.sort(arr, 0, half);
// Sort the second half
Arrays.sort(arr, half, n);
int j = half;
int count = 0;
// Process every element of the first half
for (int i = 0; i < half; i++) {
// Find all valid elements in the second half
while (j < n && (long) arr[i] >= 5L * arr[j]) {
j++;
}
// All elements from half to j-1 are valid
count += j - half;
}
return count;
}
}
7. Code Explanation
Step 1: Find the middle
int n = arr.length;
int half = n / 2;
For:
arr = [10, 8, 2, 1, 1, 2]
we have:
n = 6
half = 3
So:
First half → indices 0, 1, 2
Second half → indices 3, 4, 5
Step 2: Sort Both Halves
Arrays.sort(arr, 0, half);
Arrays.sort(arr, half, n);
This sorts each half independently.
For example:
Before:
[10, 8, 2, 1, 1, 2]
After:
[2, 8, 10, 1, 1, 2]
Notice that we do not sort the entire array.
We only sort:
[0, half)
and:
[half, n)
because the first and second halves must remain separate.
8. Initialize the Second Pointer
int j = half;

Join the conversation! Your thoughts help the community grow.