Count pairs in an array that hold i*arr[i] > j*arr[j]
Last Updated :
13 Mar, 2023
Given an array of integers arr[0..n-1], count all pairs (arr[i], arr[j]) in the such that i*arr[i] > j*arr[j], 0 =< i < j < n.
Examples :
Input : arr[] = {5 , 0, 10, 2, 4, 1, 6}
Output: 5
Pairs which hold condition i*arr[i] > j*arr[j]
are (10, 2) (10, 4) (10, 1) (2, 1) (4, 1)
Input : arr[] = {8, 4, 2, 1}
Output : 2
A Simple solution is to run two loops. Pick each element of the array one by one and for each element find an element on the right side of the array that holds the condition, then increment the counter, and last return the counter value.
Below is the implementation of the above idea:
C++
#include<iostream>
using namespace std;
int CountPair( int arr[] , int n )
{
int result = 0;
for ( int i=0; i<n; i++)
{
for ( int j = i + 1; j < n; j++)
if (i*arr[i] > j*arr[j] )
result ++;
}
return result;
}
int main()
{
int arr[] = {5 , 0, 10, 2, 4, 1, 6} ;
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Count of Pairs : "
<< CountPair(arr, n);
return 0;
}
|
Java
class GFG {
public static int CountPair( int arr[] , int n )
{
int result = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
if (i*arr[i] > j*arr[j] )
result ++;
}
return result;
}
public static void main(String[] args)
{
int arr[] = { 5 , 0 , 10 , 2 , 4 , 1 , 6 } ;
int n = arr.length;
System.out.println( "Count of Pairs : " +
CountPair(arr, n));
}
}
|
Python3
def CountPair(arr , n ):
result = 0 ;
for i in range ( 0 , n):
j = i + 1
while (j < n):
if (i * arr[i] > j * arr[j] ):
result = result + 1
j = j + 1
return result;
arr = [ 5 , 0 , 10 , 2 , 4 , 1 , 6 ]
n = len (arr)
print ( "Count of Pairs : " , CountPair(arr, n))
|
C#
using System;
class GFG
{
public static int CountPair( int []arr , int n )
{
int result = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
if (i*arr[i] > j*arr[j] )
result ++;
}
return result;
}
public static void Main()
{
int []arr = {5, 0, 10, 2, 4, 1, 6};
int n = arr.Length;
Console.WriteLine( "Count of Pairs : " +
CountPair(arr, n));
}
}
|
PHP
<?php
function CountPair( $arr , $n )
{
$result = 0;
for ( $i = 0; $i < $n ; $i ++)
{
for ( $j = $i + 1; $j < $n ; $j ++)
if ( $i * $arr [ $i ] > $j * $arr [ $j ] )
$result ++;
}
return $result ;
}
$arr = array (5, 0, 10, 2, 4, 1, 6) ;
$n = sizeof( $arr );
echo "Count of Pairs : " ,
CountPair( $arr , $n );
?>
|
Javascript
<script>
function CountPair(arr, n)
{
let result = 0;
for (let i = 0; i < n; i++)
{
for (let j = i + 1; j < n; j++)
if (i * arr[i] > j * arr[j] )
result ++;
}
return result;
}
let arr = [5 , 0, 10, 2, 4, 1, 6] ;
let n = arr.length;
document.write( "Count of Pairs : " +
CountPair(arr, n));
</script>
|
Output
Count of Pairs : 5
Time Complexity: O(n2)
Auxiliary Space: O(1)
An efficient solution to this problem takes O(n log n) time. The idea is based on an interesting fact about this problem after modifying the array such that every element is multiplied by its index, this problem converts into Count Inversions in an array.
Algorithm :
Given an array ‘arr’ and it’s size ‘n’
- First traversal array element, i goes from 0 to n-1
- Multiple each element with its index arr[i] = arr[i] * i
- After that step 1. whole process is similar to Count Inversions in an array.
Below is the implementation of the above idea
C++
#include <bits/stdc++.h>
using namespace std;
int merge( int arr[], int temp[], int left,
int mid, int right)
{
int inv_count = 0;
int i = left;
int j = mid;
int k = left;
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
while (i <= mid - 1)
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (i=left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
int _mergeSort( int arr[], int temp[], int left,
int right)
{
int mid, inv_count = 0;
if (right > left)
{
mid = (right + left)/2;
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
int countPairs( int arr[], int n)
{
for ( int i=0; i<n; i++)
arr[i] = i*arr[i];
int temp[n];
return _mergeSort(arr, temp, 0, n - 1);
}
int main()
{
int arr[] = {5, 0, 10, 2, 4, 1, 6};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Count of Pairs : "
<< countPairs(arr, n);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int merge( int arr[], int temp[], int left,
int mid, int right)
{
int inv_count = 0 ;
int i = left;
int j = mid;
int k = left;
while ((i <= mid - 1 ) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
while (i <= mid - 1 )
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
static int _mergeSort( int arr[], int temp[],
int left, int right)
{
int mid, inv_count = 0 ;
if (right > left)
{
mid = (right + left) / 2 ;
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+ 1 , right);
inv_count += merge(arr, temp, left, mid+ 1 , right);
}
return inv_count;
}
static int countPairs( int arr[], int n)
{
for ( int i = 0 ; i < n; i++)
arr[i] = i * arr[i];
int temp[] = new int [n];
return _mergeSort(arr, temp, 0 , n - 1 );
}
public static void main (String[] args)
{
int arr[] = { 5 , 0 , 10 , 2 , 4 , 1 , 6 };
int n = arr.length;
System.out.print( "Count of Pairs : "
+ countPairs(arr, n));
}
}
|
Python3
def merge(arr, temp, left, mid, right):
inv_count = 0
i = left
j = mid
k = left
while ((i < = mid - 1 ) and (j < = right)):
if (arr[i] < = arr[j]):
temp[k] = arr[i]
i + = 1
k + = 1
else :
temp[k] = arr[j]
k + = 1
j + = 1
inv_count = inv_count + (mid - i)
while (i < = mid - 1 ):
temp[k] = arr[i]
i + = 1
k + = 1
while (j < = right):
temp[k] = arr[j]
k + = 1
j + = 1
for i in range (left, right + 1 ):
arr[i] = temp[i]
return inv_count
def _mergeSort(arr, temp, left, right):
inv_count = 0
if (right > left):
mid = (right + left) / / 2
inv_count = _mergeSort(arr, temp, left, mid)
inv_count + = _mergeSort(arr, temp,
mid + 1 , right)
inv_count + = merge(arr, temp, left,
mid + 1 , right)
return inv_count
def countPairs(arr, n):
for i in range (n):
arr[i] = i * arr[i]
temp = [ 0 ] * n
return _mergeSort(arr, temp, 0 , n - 1 )
if __name__ = = "__main__" :
arr = [ 5 , 0 , 10 , 2 , 4 , 1 , 6 ]
n = len (arr)
print ( "Count of Pairs : " ,
countPairs(arr, n))
|
C#
using System;
class GFG
{
static int merge( int []arr, int []temp, int left,
int mid, int right)
{
int inv_count = 0;
int i = left;
int j = mid;
int k = left;
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
while (i <= mid - 1)
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
static int _mergeSort( int []arr, int []temp,
int left, int right)
{
int mid, inv_count = 0;
if (right > left)
{
mid = (right + left) / 2;
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
static int countPairs( int []arr, int n)
{
for ( int i = 0; i < n; i++)
arr[i] = i * arr[i];
int []temp = new int [n];
return _mergeSort(arr, temp, 0, n - 1);
}
public static void Main ()
{
int []arr = {5, 0, 10, 2, 4, 1, 6};
int n = arr.Length;
Console.WriteLine( "Count of Pairs : "
+ countPairs(arr, n));
}
}
|
Javascript
<script>
function merge(arr,temp,left,mid,right)
{
let inv_count = 0;
let i = left;
let j = mid;
let k = left;
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
while (i <= mid - 1)
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
function _mergeSort(arr,temp,left,right)
{
let mid, inv_count = 0;
if (right > left)
{
mid = Math.floor((right + left) / 2);
inv_count = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}
function countPairs(arr,n)
{
for (let i = 0; i < n; i++)
arr[i] = i * arr[i];
let temp = new Array(n);
for (let i=0;i<temp;i++)
{
temp[i]=0;
}
return _mergeSort(arr, temp, 0, n - 1);
}
let arr=[5, 0, 10, 2, 4, 1, 6];
let n = arr.length;
document.write( "Count of Pairs : "
+ countPairs(arr, n));
</script>
|
Output
Count of Pairs : 5
Time Complexity: O(n log n)
Auxiliary Space: O(n)
Another efficient approach (Using policy-based data structures in C++ STL):
In this approach, we first store the value i*arr[i] for every index i and let name this array obtained as a modified array. So now instead of i*arr[i]>j*arr[j] in the original array, we have to find x>y where x and y are now elements of the modified array where the index of x is smaller than the index of y. In other words for every index i in the modified array, the total number of such pairs is the count of all the smaller elements to the right side of that index.
Hence the problem is transformed into another problem where we need to find the count of the smaller elements to the right side for each index i in the modified array.
So we can solve this problem efficiently by maintaining a policy-based data structure of pairs.
The steps involved are:
- Traverse through the array and for each index i store i*arr[i].
- Then traverse through the modified array from the end and every time we find the order_of_key of the current element to find the number of smaller elements to the right of it.
- Then we will add the obtained value from order_of_key of the current element into the ans variable.
- After that, we will insert the current element into our policy-based data structure.
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pbds \
tree<pair< int , int >, null_type, less<pair< int , int > >, \
rb_tree_tag, tree_order_statistics_node_update>
using namespace __gnu_pbds;
using namespace std;
void countPrint( int arr[], int n)
{
for ( int i=0;i<n;i++)
{
arr[i]=i*arr[i];
}
pbds s;
int ans=0;
for ( int i = n - 1; i >= 0; i--) {
if (i!=n-1) {
ans+=s.order_of_key({ arr[i], i });
}
s.insert({ arr[i], i });
}
cout << ans << endl;
}
int main()
{
int n = 7;
int arr[] = { 5 , 0, 10, 2, 4, 1, 6 };
countPrint(arr, n);
return 0;
}
|
Java
import java.util.*;
import java.util.AbstractMap.SimpleEntry;
public class Main {
static void countPrint( int [] arr, int n)
{
for ( int i = 0 ; i < n; i++) {
arr[i] = i * arr[i];
}
TreeMap<Integer, Integer> s = new TreeMap<>();
int ans = 0 ;
for ( int i = n - 1 ; i >= 0 ; i--)
{
if (i != n - 1 )
{
ans += s.headMap(arr[i]).size();
}
s.put(arr[i], i);
}
System.out.println(ans);
}
public static void main(String[] args) {
int n = 7 ;
int [] arr = { 5 , 0 , 10 , 2 , 4 , 1 , 6 };
countPrint(arr, n);
}
}
|
Python3
from bisect import bisect_left
def countPrint(arr, n):
for i in range (n):
arr[i] = i * arr[i]
s = []
ans = 0
for i in range (n - 1 , - 1 , - 1 ):
if i ! = n - 1 :
ans + = bisect_left(s, arr[i])
s.insert(bisect_left(s, arr[i]), arr[i])
print (ans)
if __name__ = = '__main__' :
n = 7
arr = [ 5 , 0 , 10 , 2 , 4 , 1 , 6 ]
countPrint(arr, n)
|
C#
using System;
using System.Collections.Generic;
class MainClass {
static void countPrint( int [] arr, int n)
{
for ( int i = 0; i < n; i++) {
arr[i] = i * arr[i];
}
List< int > s = new List< int >();
int ans = 0;
for ( int i = n - 1; i >= 0; i--) {
if (i != n - 1) {
ans += s.BinarySearch(arr[i]) >= 0
? s.BinarySearch(arr[i])
: ~s.BinarySearch(arr[i]);
}
s.Insert(s.BinarySearch(arr[i]) >= 0
? s.BinarySearch(arr[i])
: ~s.BinarySearch(arr[i]),
arr[i]);
}
Console.WriteLine(ans);
}
public static void Main( string [] args)
{
int n = 7;
int [] arr = { 5, 0, 10, 2, 4, 1, 6 };
countPrint(arr, n);
}
}
|
Javascript
function countPrint(arr, n) {
for (let i = 0; i < n; i++) {
arr[i] = i * arr[i];
}
const s = new Map();
let ans = 0;
for (let i = n - 1; i >= 0; i--) {
if (i != n - 1) {
for (const [key, value] of s.entries()) {
if (key < arr[i]) {
ans += value;
}
}
}
if (s.has(arr[i])) {
s.set(arr[i], s.get(arr[i]) + 1);
} else {
s.set(arr[i], 1);
}
}
console.log(ans);
}
const n = 7;
const arr = [5, 0, 10, 2, 4, 1, 6];
countPrint(arr, n);
|
Time Complexity: O(n*log(n))
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...