Given an even-sized array arr[] of length n. A dominant pair (i, j) is defined as:
- i belongs to the first half of the array, (0 <= i < n/2)
- j belongs to the second half of the array, (n/2 <= j < n)
- The value at index i is at least five times the value at index j, (arr[i] >= 5 * arr[j])
The task is to find the count of total number of dominant pairs in the array.
Examples:
Input: arr[] = [10, 2, 2, 1]
Output: 2
Explanation: First half: [10, 2], Second half: [2, 1]. So valid pairs are:
- {0, 2}: 10 >= 5 × 2
- {0, 3}: 10 >= 5 × 1
So, total dominant pairs = 2.
Input: arr[] = [10, 8, 2, 1, 1, 2]
Output: 5
Explanation: First half: [10, 8, 2], Second half: [1, 1, 2]. So valid pairs are:
- {0, 3}: 10 >= 5 × 1
- {0, 4}: 10 >= 5 × 1
- {0, 5}: 10 >= 5 × 2
- {1, 3}: 8 >= 5 × 1
- {1, 4}: 8 >= 5 × 1
So, total dominant pairs = 5.
Table of Content
[Brute-Force Approach] Using 2 Nested Loops - O(n²) Time and O(1) Space
The idea is to count dominant pairs by checking all possible (i, j) pairs where i belongs to the first half and j belongs to the second half of the array. The brute-force approach uses two nested loops to compare each element from the first half with every element from the second half, ensuring the dominance condition (arr[i] >=5 * arr[j]) holds.
// C++ Code to find number of dominant pairs
// in an array using 2 Nested Loops
#include <bits/stdc++.h>
using namespace std;
int dominantPairs(vector<int> &arr) {
int n = arr.size();
int count = 0;
// Iterate through the first half of the array
for (int i = 0; i < n / 2; i++) {
// Iterate through the second half of
// the array
for (int j = n / 2; j < n; j++) {
// Check if arr[i] satisfies the
// dominance condition
if (arr[i] >= 5 * arr[j]) {
count++;
}
}
}
return count;
}
// Driver code
int main() {
vector<int> arr = {10, 2, 2, 1};
cout << dominantPairs(arr) << endl;
return 0;
}
// Java Code to find number of dominant pairs
// in an array using 2 Nested Loops
import java.util.*;
class GfG {
static int dominantPairs(int[] arr) {
int n = arr.length;
int count = 0;
// Iterate through the first half of the array
for (int i = 0; i < n / 2; i++) {
// Iterate through the second half of
// the array
for (int j = n / 2; j < n; j++) {
// Check if arr[i] satisfies the
// dominance condition
if (arr[i] >= 5 * arr[j]) {
count++;
}
}
}
return count;
}
// Driver code
public static void main(String[] args) {
int[] arr = {10, 2, 2, 1};
System.out.println(dominantPairs(arr));
}
}
# Python Code to find number of dominant pairs
# in an array using 2 Nested Loops
def dominantPairs(arr):
n = len(arr)
count = 0
# Iterate through the first half of the array
for i in range(n // 2):
# Iterate through the second half of
# the array
for j in range(n // 2, n):
# Check if arr[i] satisfies the
# dominance condition
if arr[i] >= 5 * arr[j]:
count += 1
return count
# Driver code
if __name__ == "__main__":
arr = [10, 2, 2, 1]
print(dominantPairs(arr))
// C# Code to find number of dominant pairs
// in an array using 2 Nested Loops
using System;
class GfG {
static int dominantPairs(int[] arr) {
int n = arr.Length;
int count = 0;
// Iterate through the first half of the array
for (int i = 0; i < n / 2; i++) {
// Iterate through the second half of
// the array
for (int j = n / 2; j < n; j++) {
// Check if arr[i] satisfies the
// dominance condition
if (arr[i] >= 5 * arr[j]) {
count++;
}
}
}
return count;
}
// Driver code
static void Main() {
int[] arr = {10, 2, 2, 1};
Console.WriteLine(dominantPairs(arr));
}
}
// JavaScript Code to find number of dominant pairs
// in an array using 2 Nested Loops
function dominantPairs(arr) {
let n = arr.length;
let count = 0;
// Iterate through the first half of the array
for (let i = 0; i < n / 2; i++) {
// Iterate through the second half of
// the array
for (let j = n / 2; j < n; j++) {
// Check if arr[i] satisfies the
// dominance condition
if (arr[i] >= 5 * arr[j]) {
count++;
}
}
}
return count;
}
// Driver code
let arr = [10, 2, 2, 1];
console.log(dominantPairs(arr));
Output
2
Time Complexity: O(n²), due to two nested loops iterating.
Space Complexity: O(1), as only a few extra variables are used.
[Expected Approach] Using Sorting + Two Pointers - O(n*log(n)) Time and O(1) Space
The idea is to efficiently count dominant pairs by leveraging sorting and the two-pointer technique. Instead of using nested loops, we sort the first half and second half separately to maintain order. Using a two-pointer approach, we iterate through the first half and move the right pointer in the second half until the dominance condition is violated. This ensures that for every valid left index, all valid right indices are counted efficiently.
Steps to implement the above idea:
- Sort the first half of the array in ascending order and the second half of the array in ascending order to allow efficient comparison using a two-pointer approach.
- Initialize a count variable to store the number of dominant pairs and set a right pointer at the start of the second half.
- Iterate through the first half of the array using a left pointer to find valid dominant pairs efficiently.
- Move the right pointer forward while the dominance condition (arr[left] >= 5 * arr[right]) holds true.
- Update the count variable by adding the number of valid elements in the second half that satisfy the condition.
- Return the final count, which represents the total number of dominant pairs found in the given array.
Below is the implementation of the above approach:
// C++ Code to find number of dominant pairs
// using Sorting and Two Pointers
#include <bits/stdc++.h>
using namespace std;
int dominantPairs(vector<int> &arr) {
int n = arr.size();
// Sort the first half in ascending order
sort(arr.begin(), arr.begin() + n / 2);
// Sort the second half in ascending order
sort(arr.begin() + n / 2, arr.end());
int count = 0;
int right = n / 2;
// Iterate through the first half of the array
for (int left = 0; left < n / 2; left++) {
// Move right pointer while dominance condition holds
while (right < n && arr[left] >= 5 * arr[right]) {
right++;
}
// Count dominant pairs
count += (right - n / 2);
}
return count;
}
// Driver code
int main() {
vector<int> arr = {10, 2, 2, 1};
cout << dominantPairs(arr) << endl;
return 0;
}
// Java Code to find number of dominant pairs
// using Sorting and Two Pointers
import java.util.Arrays;
class GfG {
static int dominantPairs(int[] arr) {
int n = arr.length;
// Sort the first half in ascending order
Arrays.sort(arr, 0, n / 2);
// Sort the second half in ascending order
Arrays.sort(arr, n / 2, n);
int count = 0;
int right = n / 2;
// Iterate through the first half of the array
for (int left = 0; left < n / 2; left++) {
// Move right pointer while dominance condition holds
while (right < n && arr[left] >= 5 * arr[right]) {
right++;
}
// Count dominant pairs
count += (right - n / 2);
}
return count;
}
// Driver code
public static void main(String[] args) {
int[] arr = {10, 2, 2, 1};
System.out.println(dominantPairs(arr));
}
}
# Python Code to find number of dominant pairs
# using Sorting and Two Pointers
def dominantPairs(arr):
n = len(arr)
# Sort the first half in ascending order
arr[:n//2] = sorted(arr[:n//2])
# Sort the second half in ascending order
arr[n//2:] = sorted(arr[n//2:])
count = 0
right = n // 2
# Iterate through the first half of the array
for left in range(n // 2):
# Move right pointer while dominance condition holds
while right < n and arr[left] >= 5 * arr[right]:
right += 1
# Count dominant pairs
count += (right - n // 2)
return count
# Driver code
if __name__ == "__main__":
arr = [10, 2, 2, 1]
print(dominantPairs(arr))
// C# Code to find number of dominant pairs
// using Sorting and Two Pointers
using System;
class GfG {
static int dominantPairs(int[] arr) {
int n = arr.Length;
// Sort the first half in ascending order
Array.Sort(arr, 0, n / 2);
// Sort the second half in ascending order
Array.Sort(arr, n / 2, n - n / 2);
int count = 0;
int right = n / 2;
// Iterate through the first half of the array
for (int left = 0; left < n / 2; left++) {
// Move right pointer while dominance condition holds
while (right < n && arr[left] >= 5 * arr[right]) {
right++;
}
// Count dominant pairs
count += (right - n / 2);
}
return count;
}
// Driver code
public static void Main() {
int[] arr = {10, 2, 2, 1};
Console.WriteLine(dominantPairs(arr));
}
}
// JavaScript Code to find number of dominant pairs
// using Sorting and Two Pointers
function dominantPairs(arr) {
let n = arr.length;
// Sort the first half in ascending order
arr.splice(0, n / 2, ...arr.slice(0, n / 2).sort((a, b) => a - b));
// Sort the second half in ascending order
arr.splice(n / 2, n / 2, ...arr.slice(n / 2).sort((a, b) => a - b));
let count = 0;
let right = n / 2;
// Iterate through the first half of the array
for (let left = 0; left < n / 2; left++) {
// Move right pointer while dominance condition holds
while (right < n && arr[left] >= 5 * arr[right]) {
right++;
}
// Count dominant pairs
count += (right - n / 2);
}
return count;
}
// Driver code
let arr = [10, 2, 2, 1];
console.log(dominantPairs(arr));
Output
2
Time Complexity: O(n*log(n)), as sorting takes O(n log n), and two-pointer traversal takes O(n).
Space Complexity: O(1), as sorting is done in-place, and only a few extra variables are used.