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

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

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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);
    }
}

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


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.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : 29AjayKumar