Given an array arr[] of N integers, the task is to count the number of smaller elements on the right side for each of the element in the array
Examples:
Input: arr[] = {6, 3, 7, 2}
Output: 2, 1, 1, 0
Explanation:
Smaller elements after 6 = 2 [3, 2]
Smaller elements after 3 = 1 [2]
Smaller elements after 7 = 1 [2]
Smaller elements after 2 = 0Input: arr[] = {6, 19, 111, 13}
Output: 0, 1, 1, 0
Explanation:
Smaller elements after 6 = 0
Smaller elements after 19 = 1 [13]
Smaller elements after 111 = 1 [13]
Smaller elements after 13 = 0
Approach:
Use the idea of the merge sort at the time of merging two arrays. When higher index element is less than the lower index element, it represents that the higher index element is smaller than all the elements after that lower index because the left part is already sorted. Hence add up to all the elements after the lower index element for the required count.
Below is the implementation of the above approach
// C++ program to find the count of // smaller elements on right side of // each element in an Array // using Merge sort #include <bits/stdc++.h> using namespace std;
const int N = 100001;
int ans[N];
// Utility function that merge the array // and count smaller element on right side void merge(pair< int , int > a[], int start,
int mid, int end)
{ pair< int , int > f[mid - start + 1],
s[end - mid];
int n = mid - start + 1;
int m = end - mid;
for ( int i = start; i <= mid; i++)
f[i - start] = a[i];
for ( int i = mid + 1; i <= end; i++)
s[i - mid - 1] = a[i];
int i = 0, j = 0, k = start;
int cnt = 0;
// Loop to store the count of smaller
// Elements on right side when both
// Array have some elements
while (i < n && j < m)
{
if (f[i].second <= s[j].second)
{
ans[f[i].first] += cnt;
a[k++] = f[i++];
}
else
{
cnt++;
a[k++] = s[j++];
}
}
// Loop to store the count of smaller
// elements in right side when only
// left array have some element
while (i < n)
{
ans[f[i].first] += cnt;
a[k++] = f[i++];
}
// Loop to store the count of smaller
// elements in right side when only
// right array have some element
while (j < m)
{
a[k++] = s[j++];
}
} // Function to invoke merge sort. void mergesort(pair< int , int > item[],
int low, int high)
{ if (low >= high)
return ;
int mid = (low + high) / 2;
mergesort(item, low, mid);
mergesort(item, mid + 1, high);
merge(item, low, mid, high);
} // Utility function that prints // out an array on a line void print( int arr[], int n)
{ for ( int i = 0; i < n; i++)
cout << arr[i] << " " ;
} // Driver code. int main()
{ int arr[] = { 10, 9, 5, 2, 7,
6, 11, 0, 2 };
int n = sizeof (arr) / sizeof ( int );
pair< int , int > a[n];
memset (ans, 0, sizeof (ans));
for ( int i = 0; i < n; i++)
{
a[i].second = arr[i];
a[i].first = i;
}
mergesort(a, 0, n - 1);
print(ans, n);
return 0;
} // This code is contributed by rishabhtyagi2306 |
// Java program to find the count of smaller elements // on right side of each element in an Array // using Merge sort import java.util.*;
public class GFG {
// Class for storing the index
// and Value pairs
class Item {
int val;
int index;
public Item( int val, int index)
{
this .val = val;
this .index = index;
}
}
// Function to count the number of
// smaller elements on right side
public ArrayList<Integer> countSmall( int [] A)
{
int len = A.length;
Item[] items = new Item[len];
for ( int i = 0 ; i < len; i++) {
items[i] = new Item(A[i], i);
}
int [] count = new int [len];
mergeSort(items, 0 , len - 1 , count);
ArrayList<Integer> res = new ArrayList<>();
for ( int i : count) {
res.add(i);
}
return res;
}
// Function for Merge Sort
private void mergeSort(Item[] items,
int low, int high,
int [] count)
{
if (low >= high) {
return ;
}
int mid = low + (high - low) / 2 ;
mergeSort(items, low, mid, count);
mergeSort(items, mid + 1 , high, count);
merge(items, low, mid, mid + 1 , high, count);
}
// Utility function that merge the array
// and count smaller element on right side
private void merge(Item[] items, int low,
int lowEnd, int high,
int highEnd, int [] count)
{
int m = highEnd - low + 1 ;
Item[] sorted = new Item[m];
int rightCounter = 0 ;
int lowPtr = low, highPtr = high;
int index = 0 ;
// Loop to store the count of smaller
// Elements on right side when both
// Array have some elements
while (lowPtr <= lowEnd && highPtr <= highEnd) {
if (items[lowPtr].val > items[highPtr].val) {
rightCounter++;
sorted[index++] = items[highPtr++];
}
else {
count[items[lowPtr].index] += rightCounter;
sorted[index++] = items[lowPtr++];
}
}
// Loop to store the count of smaller
// elements in right side when only
// left array have some element
while (lowPtr <= lowEnd) {
count[items[lowPtr].index] += rightCounter;
sorted[index++] = items[lowPtr++];
}
// Loop to store the count of smaller
// elements in right side when only
// right array have some element
while (highPtr <= highEnd) {
sorted[index++] = items[highPtr++];
}
System.arraycopy(sorted, 0 , items, low, m);
}
// Utility function that prints
// out an array on a line
void printArray(ArrayList<Integer> countList)
{
for (Integer i : countList)
System.out.print(i + " " );
System.out.println( "" );
}
// Driver Code
public static void main(String[] args)
{
GFG cntSmall = new GFG();
int arr[] = { 10 , 9 , 5 , 2 , 7 , 6 , 11 , 0 , 2 };
int n = arr.length;
ArrayList<Integer> countList
= cntSmall.countSmall(arr);
cntSmall.printArray(countList);
}
} |
# Python3 program to find the count of # smaller elements on right side of # each element in an Array # using Merge sort N = 100001
ans = [ 0 ] * N
# Utility function that merge the array # and count smaller element on right side def merge(a, start, mid, end):
f = [ 0 ] * (mid - start + 1 )
s = [ 0 ] * (end - mid)
n = mid - start + 1
m = end - mid
for i in range (start, mid + 1 ):
f[i - start] = a[i]
for i in range ( mid + 1 , end + 1 ):
s[i - mid - 1 ] = a[i]
i = 0
j = 0
k = start
cnt = 0
# Loop to store the count of smaller
# Elements on right side when both
# Array have some elements
while (i < n and j < m):
if (f[i][ 1 ] < = s[j][ 1 ]):
ans[f[i][ 0 ]] + = cnt
a[k] = f[i]
k + = 1
i + = 1
else :
cnt + = 1
a[k] = s[j]
k + = 1
j + = 1
# Loop to store the count of smaller
# elements in right side when only
# left array have some element
while (i < n):
ans[f[i][ 0 ]] + = cnt
a[k] = f[i];
k + = 1
i + = 1
# Loop to store the count of smaller
# elements in right side when only
# right array have some element
while (j < m):
a[k] = s[j]
k + = 1
j + = 1
# Function to invoke merge sort. def mergesort(item, low, high):
if (low > = high):
return
mid = (low + high) / / 2
mergesort(item, low, mid)
mergesort(item, mid + 1 , high)
merge(item, low, mid, high)
# Utility function that prints # out an array on a line def print_(arr, n):
for i in range (n):
print (arr[i], end = " " )
# Driver code. if __name__ = = "__main__" :
arr = [ 10 , 9 , 5 , 2 , 7 ,
6 , 11 , 0 , 2 ]
n = len (arr)
a = [[ 0 for x in range ( 2 )]
for y in range (n)]
for i in range (n):
a[i][ 1 ] = arr[i]
a[i][ 0 ] = i
mergesort(a, 0 , n - 1 )
print_(ans, n)
# This code is contributed by chitranayal |
// C# program to find the count of smaller elements // on right side of each element in an Array // using Merge sort using System;
using System.Collections.Generic;
class GFG
{ // Class for storing the index
// and Value pairs
public class Item
{
public int val;
public int index;
public Item( int val, int index)
{
this .val = val;
this .index = index;
}
}
// Function to count the number of
// smaller elements on right side
public List< int > countSmall( int [] A)
{
int len = A.Length;
Item[] items = new Item[len];
for ( int i = 0; i < len; i++)
{
items[i] = new Item(A[i], i);
}
int [] count = new int [len];
mergeSort(items, 0, len - 1, count);
List< int > res = new List< int >();
foreach ( int i in count)
{
res.Add(i);
}
return res;
}
// Function for Merge Sort
private void mergeSort(Item[] items,
int low, int high,
int [] count)
{
if (low >= high)
{
return ;
}
int mid = low + (high - low) / 2;
mergeSort(items, low, mid, count);
mergeSort(items, mid + 1, high, count);
merge(items, low, mid, mid + 1, high, count);
}
// Utility function that merge the array
// and count smaller element on right side
private void merge(Item[] items, int low,
int lowEnd, int high,
int highEnd, int [] count)
{
int m = highEnd - low + 1;
Item[] sorted = new Item[m];
int rightCounter = 0;
int lowPtr = low, highPtr = high;
int index = 0;
// Loop to store the count of smaller
// Elements on right side when both
// Array have some elements
while (lowPtr <= lowEnd && highPtr <= highEnd)
{
if (items[lowPtr].val > items[highPtr].val)
{
rightCounter++;
sorted[index++] = items[highPtr++];
}
else
{
count[items[lowPtr].index] += rightCounter;
sorted[index++] = items[lowPtr++];
}
}
// Loop to store the count of smaller
// elements in right side when only
// left array have some element
while (lowPtr <= lowEnd)
{
count[items[lowPtr].index] += rightCounter;
sorted[index++] = items[lowPtr++];
}
// Loop to store the count of smaller
// elements in right side when only
// right array have some element
while (highPtr <= highEnd)
{
sorted[index++] = items[highPtr++];
}
Array.Copy(sorted, 0, items, low, m);
}
// Utility function that prints
// out an array on a line
void printArray(List< int > countList)
{
foreach ( int i in countList)
Console.Write(i + " " );
Console.WriteLine( "" );
}
// Driver Code
public static void Main(String[] args)
{
GFG cntSmall = new GFG();
int []arr = { 10, 9, 5, 2, 7, 6, 11, 0, 2 };
int n = arr.Length;
List< int > countList
= cntSmall.countSmall(arr);
cntSmall.printArray(countList);
}
} // This code is contributed by 29AjayKumar |
<script> // Javascript program to find the count of // smaller elements on right side of each // element in an Array using Merge sort let N = 100001; let ans = new Array(N);
// Utility function that merge the array // and count smaller element on right side function merge(a, start, mid, end)
{ let f = new Array((mid - start + 1));
let s = new Array(end - mid);
let n = mid - start + 1;
let m = end - mid;
for (let i = start; i <= mid; i++)
f[i - start] = a[i];
for (let i = mid + 1; i <= end; i++)
s[i - mid - 1] = a[i];
let i = 0, j = 0, k = start;
let cnt = 0;
// Loop to store the count of smaller
// Elements on right side when both
// Array have some elements
while (i < n && j < m)
{
if (f[i][1] <= s[j][1])
{
ans[f[i][0]] += cnt;
a[k++] = f[i++];
}
else
{
cnt++;
a[k++] = s[j++];
}
}
// Loop to store the count of smaller
// elements in right side when only
// left array have some element
while (i < n)
{
ans[f[i][0]] += cnt;
a[k++] = f[i++];
}
// Loop to store the count of smaller
// elements in right side when only
// right array have some element
while (j < m)
{
a[k++] = s[j++];
}
} // Function to invoke merge sort. function mergesort(item, low, high)
{ if (low >= high)
return ;
let mid = Math.floor((low + high) / 2);
mergesort(item, low, mid);
mergesort(item, mid + 1, high);
merge(item, low, mid, high);
} // Utility function that prints // out an array on a line function print(arr, n)
{ for (let i = 0; i < n; i++)
document.write(arr[i] + " " );
} // Driver Code let arr = [ 10, 9, 5, 2, 7, 6, 11, 0, 2 ]; let n = arr.length; let a = new Array(n);
for (let i = 0; i < a.length; i++)
{ a[i] = new Array(2);
} for (let i = 0; i < ans.length; i++)
{ ans[i] = 0;
} for (let i = 0; i < n; i++)
{ a[i][1] = arr[i];
a[i][0] = i;
} mergesort(a, 0, n - 1); print(ans, n); // This code is contributed by rag2127 </script> |
7 6 3 1 3 2 2 0 0
Time Complexity: O(n log n)
The time complexity for the Merge Sort algorithm is O(nlog n). This is because the merge sort algorithm first divides the array in two halves and then recursively sorts each half. This process continues until the array is completely sorted.
Space Complexity: O(n)
The space complexity for the Merge Sort algorithm is O(n). This is because the Merge Sort algorithm uses an auxiliary array in which it stores the elements of the original array while the sorting process is taking place.
Related Article: Count smaller elements on right side