Related Articles

Count of smaller elements on right side of each element in an Array using Merge sort

• Difficulty Level : Hard
• Last Updated : 02 Jun, 2021

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 = 0

Input: 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++

 // C++ program to find the count of// smaller elements on right side of// each element in an Array// using Merge sort#include using namespace std; const int N = 100001;int ans[N]; // Utility function that merge the array// and count smaller element on right sidevoid merge(pair a[], int start,                int mid, int end){    pair 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 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 linevoid 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 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

 // 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 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 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 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 countList            = cntSmall.countSmall(arr);        cntSmall.printArray(countList);    }}

Python3

 # Python3 program to find the count of# smaller elements on right side of# each element in an Array# using Merge sortN = 100001ans = [0] * N # Utility function that merge the array# and count smaller element on right sidedef 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 linedef 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#

 // C# program to find the count of smaller elements// on right side of each element in an Array// using Merge sortusing 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 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 res = new List();         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 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 countList            = cntSmall.countSmall(arr);        cntSmall.printArray(countList);    }} // This code is contributed by 29AjayKumar

Javascript


Output
7 6 3 1 3 2 2 0 0

Time Complexity: O(N log N)
Related Article: Count smaller elements on right side

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up