Open In App

Count smaller elements on Right side

Last Updated : 19 Sep, 2025
Comments
Improve
Suggest changes
51 Likes
Like
Report

Given an unsorted array arr[] of distinct integers, construct another array countSmaller[] such that countSmaller[i] contains the count of smaller elements on the right side of each element arr[i] in the array.

Examples: 

Input: arr[] =  [12, 1, 2, 3, 0, 11, 4]
Output:  [6, 1, 1, 1, 0, 1, 0]

Input: arr[] = [5, 4, 3, 2, 1]
Output:   [4, 3, 2, 1, 0]

Input: arr[] =  [1, 2, 3, 4, 5]
Output: [0, 0, 0, 0, 0]

[Naive Approach] Using Nested Loop - O(n*n) Time and O(n) Space

The idea is to use nested loops, where for each element we check how many elements on its right side are smaller than it.

C++
#include <iostream>
#include <vector>
using namespace std;

vector<int> constructLowerArray(vector<int>& arr) {
    int n = arr.size();
    vector<int> countSmaller(n, 0);
    int i, j;

    // Check for every element how many elements on right side are smaller
    for (i = 0; i < n; i++) {
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[i])
                countSmaller[i]++;
        }
    }
    return countSmaller;
}

// Utility function that prints out an array on a line
void printArray(vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << "\n";
}

// Driver code
int main() {
    vector<int> arr = {12, 1, 2, 3, 0, 11, 4};

    vector<int> low = constructLowerArray(arr);
    printArray(low);

    return 0;
}
Java
import java.util.*;

class Main {
    static ArrayList<Integer> constructLowerArray(int[] arr) {
        int n = arr.length;
        ArrayList<Integer> countSmaller = new ArrayList<>(Collections.nCopies(n, 0));

        // Check for every element how many elements on right side are smaller
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[i])
                    countSmaller.set(i, countSmaller.get(i) + 1);
            }
        }
        return countSmaller;
    }

    // Utility function that prints out an array on a line
    static void printArray(ArrayList<Integer> arr) {
        for (int x : arr)
            System.out.print(x + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {12, 1, 2, 3, 0, 11, 4};

        ArrayList<Integer> low = constructLowerArray(arr);
        printArray(low);
    }
}
Python
def constructLowerArray(arr):
    n = len(arr)
    countSmaller = [0] * n

    # Check for every element how many elements on right side are smaller
    for i in range(n):
        for j in range(i + 1, n):
            if arr[j] < arr[i]:
                countSmaller[i] += 1

    return countSmaller

# Utility function that prints out an array on a line
def printArray(arr):
    for x in arr:
        print(x, end=" ")
    print()

if __name__ =="__main__":
    arr = [12, 1, 2, 3, 0, 11, 4]
    
    low = constructLowerArray(arr)
    printArray(low)
C#
using System;
using System.Collections.Generic;

class Program {
    static List<int> ConstructLowerArray(int[] arr) {
        int n = arr.Length;
        List<int> countSmaller = new List<int>(new int[n]);

        // Check for every element how many elements on right side are smaller
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[i])
                    countSmaller[i]++;
            }
        }
        return countSmaller;
    }

    // Utility function that prints out an array on a line
    static void PrintArray(List<int> arr) {
        foreach (int x in arr)
            Console.Write(x + " ");
        Console.WriteLine();
    }

    static void Main() {
        int[] arr = {12, 1, 2, 3, 0, 11, 4};

        List<int> low = ConstructLowerArray(arr);
        PrintArray(low);
    }
}
JavaScript
function constructLowerArray(arr) {
    let n = arr.length;
    let countSmaller = new Array(n).fill(0);

    // Check for every element how many elements on right side are smaller
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            if (arr[j] < arr[i])
                countSmaller[i]++;
        }
    }
    return countSmaller;
}

// Utility function that prints out an array on a line
function printArray(arr) {
    console.log(arr.join(" "));
}

// Driver code
let arr = [12, 1, 2, 3, 0, 11, 4];

let low = constructLowerArray(arr);
printArray(low);

Output
6 1 1 1 0 1 0 

[Expected Approach] Using Merge Sort - O(nlogn) Time and O(n) Space

The idea is to use a modified merge sort. We store both element values and their original indices. While merging, we count how many elements from the right half are smaller and add this count to the corresponding index’s result.

Steps to solve the problem:

  • Store each element with its index in a pair (value, index).
  • Perform merge sort on this pair array.
  • During merging: check if a left element is greater than a right element.
  • If yes, then all remaining elements in the right half are smaller → add their count to the result of that left element’s index.
  • After counting, place elements into the merged array.
  • Otherwise, merge normally when the left element is not greater.
  • Continue recursively until the entire array is sorted.
  • The result array will finally hold the number of smaller elements on the right for each index.
C++
#include <bits/stdc++.h>
using namespace std;

void merge(vector<pair<int, int>>& v, vector<int>& ans, int l, int mid, int h) {
    
    // temporary array for merging both halves
    vector<pair<int, int>> t; 
    int i = l;
    int j = mid + 1;

    while (i < mid + 1 && j <= h) {
        
        // v[i].first is greater than 
        // all the elements from j till h.
        if (v[i].first > v[j].first) {
            ans[v[i].second] += (h - j + 1);
            t.push_back(v[i]);
            i++;
        } else {
            t.push_back(v[j]);
            j++;
        }
    }

    // if any elements left in left array
    while (i <= mid)
        t.push_back(v[i++]);
        
    // if any elements left in right array
    while (j <= h)
        t.push_back(v[j++]);

    // putting elements back in main array 
    // in descending order
    for (int k = 0, idx = l; idx <= h; idx++, k++)
        v[idx] = t[k];
}

void mergesort(vector<pair<int, int>>& v, vector<int>& ans, int i, int j) {
    if (i < j) {
        int mid = (i + j) / 2;

        // calling mergesort for left half
        mergesort(v, ans, i, mid);

        // calling mergesort for right half
        mergesort(v, ans, mid + 1, j);

        // merging both halves and generating answer
        merge(v, ans, i, mid, j);
    }
}

vector<int> constructLowerArray(vector<int>& arr) {
    int n = arr.size();

    vector<pair<int, int>> v;
    
    // inserting elements and corresponding index as pair
    for (int i = 0; i < n; i++)
        v.push_back({arr[i], i});

    // answer array for keeping count initialized by 0
    vector<int> ans(n, 0);

    // calling mergesort
    mergesort(v, ans, 0, n - 1);

    return ans;
}

// Utility function to print an array
void printArray(vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << "\n";
}

int main() {
    vector<int> arr = {12, 1, 2, 3, 0, 11, 4};

    vector<int> ans = constructLowerArray(arr);
    printArray(ans);

    return 0;
}
Java
import java.util.*;

class GFG {
    static void merge(List<int[]> v, ArrayList<Integer> ans, int l, int mid, int h) {
        
        // temporary array for merging both halves
        List<int[]> t = new ArrayList<>(); 
        int i = l, j = mid + 1;

        while (i < mid + 1 && j <= h) {
            
            // v.get(i)[0] is greater than all
            // the elements from j till h
            if (v.get(i)[0] > v.get(j)[0]) {
                ans.set(v.get(i)[1], ans.get(v.get(i)[1]) + (h - j + 1));
                t.add(v.get(i));
                i++;
            } else {
                t.add(v.get(j));
                j++;
            }
        }

        // if any elements left in left array
        while (i <= mid) t.add(v.get(i++));
        
        // if any elements left in right array
        while (j <= h) t.add(v.get(j++));

        // putting elements back in main array in descending order
        for (int k = 0, idx = l; idx <= h; idx++, k++)
            v.set(idx, t.get(k));
    }

    static void mergesort(List<int[]> v, ArrayList<Integer> ans, int i, int j) {
        if (i < j) {
            int mid = (i + j) / 2;

            // calling mergesort for left half
            mergesort(v, ans, i, mid);

            // calling mergesort for right half
            mergesort(v, ans, mid + 1, j);

            // merging both halves and generating answer
            merge(v, ans, i, mid, j);
        }
    }

    static ArrayList<Integer> constructLowerArray(int[] arr) {
        int n = arr.length;

        List<int[]> v = new ArrayList<>();
        
        // inserting elements and corresponding index as pair
        for (int i = 0; i < n; i++)
            v.add(new int[]{arr[i], i});

        // answer array for keeping count initialized by 0
        ArrayList<Integer> ans = new ArrayList<>(Collections.nCopies(n, 0));

        // calling mergesort
        mergesort(v, ans, 0, n - 1);

        return ans;
    }

    // Utility function to print an array
    static void printArray(ArrayList<Integer> arr) {
        for (int x : arr) System.out.print(x + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        int[] arr = {12, 1, 2, 3, 0, 11, 4};
        ArrayList<Integer> ans = constructLowerArray(arr);
        printArray(ans);
    }
}
Python
def merge(v, ans, l, mid, h):
    t = []  # temporary array for merging both halves
    i, j = l, mid + 1

    while i < mid + 1 and j <= h:
        # v[i][0] is greater than all the elements from j till h
        if v[i][0] > v[j][0]:
            ans[v[i][1]] += (h - j + 1)
            t.append(v[i])
            i += 1
        else:
            t.append(v[j])
            j += 1

    # if any elements left in left array
    while i <= mid:
        t.append(v[i]); i += 1
    # if any elements left in right array
    while j <= h:
        t.append(v[j]); j += 1

    # putting elements back in main array in descending order
    for k, idx in enumerate(range(l, h + 1)):
        v[idx] = t[k]


def mergesort(v, ans, i, j):
    if i < j:
        mid = (i + j) // 2

        # calling mergesort for left half
        mergesort(v, ans, i, mid)

        # calling mergesort for right half
        mergesort(v, ans, mid + 1, j)

        # merging both halves and generating answer
        merge(v, ans, i, mid, j)


def constructLowerArray(arr):
    n = len(arr)

    # inserting elements and corresponding index as pair
    v = [(arr[i], i) for i in range(n)]

    # answer array for keeping count initialized by 0
    ans = [0] * n

    # calling mergesort
    mergesort(v, ans, 0, n - 1)

    return ans


# Utility function to print an array
def printArray(arr):
    print(" ".join(map(str, arr)))


if __name__ =="__main__":
    arr = [12, 1, 2, 3, 0, 11, 4]
    ans = constructLowerArray(arr)
    printArray(ans)
C#
using System;
using System.Collections.Generic;

class GFG {
    static void Merge(List<int[]> v, List<int> ans, int l, int mid, int h) {
        List<int[]> t = new List<int[]>(); // temporary array for merging both halves
        int i = l, j = mid + 1;

        while (i < mid + 1 && j <= h) {
            // v[i][0] is greater than all the elements from j till h
            if (v[i][0] > v[j][0]) {
                ans[v[i][1]] += (h - j + 1);
                t.Add(v[i]);
                i++;
            } else {
                t.Add(v[j]);
                j++;
            }
        }

        // if any elements left in left array
        while (i <= mid) t.Add(v[i++]);
        // if any elements left in right array
        while (j <= h) t.Add(v[j++]);

        // putting elements back in main array in descending order
        for (int k = 0, idx = l; idx <= h; idx++, k++)
            v[idx] = t[k];
    }

    static void MergeSort(List<int[]> v, List<int> ans, int i, int j) {
        if (i < j) {
            int mid = (i + j) / 2;

            // calling mergesort for left half
            MergeSort(v, ans, i, mid);

            // calling mergesort for right half
            MergeSort(v, ans, mid + 1, j);

            // merging both halves and generating answer
            Merge(v, ans, i, mid, j);
        }
    }

    static List<int> ConstructLowerArray(int[] arr) {
        int n = arr.Length;

        List<int[]> v = new List<int[]>();
        // inserting elements and corresponding index as pair
        for (int i = 0; i < n; i++)
            v.Add(new int[] { arr[i], i });

        // answer array for keeping count initialized by 0
        List<int> ans = new List<int>(new int[n]);

        // calling mergesort
        MergeSort(v, ans, 0, n - 1);

        return ans;
    }

    // Utility function to print an array
    static void PrintArray(List<int> arr) {
        foreach (int x in arr)
            Console.Write(x + " ");
        Console.WriteLine();
    }

    static void Main() {
        int[] arr = { 12, 1, 2, 3, 0, 11, 4 };
        List<int> ans = ConstructLowerArray(arr);
        PrintArray(ans);
    }
}
JavaScript
function merge(v, ans, l, mid, h) {
    let t = []; // temporary array for merging both halves
    let i = l, j = mid + 1;

    while (i < mid + 1 && j <= h) {
        // v[i][0] is greater than all the elements from j till h
        if (v[i][0] > v[j][0]) {
            ans[v[i][1]] += (h - j + 1);
            t.push(v[i]);
            i++;
        } else {
            t.push(v[j]);
            j++;
        }
    }

    // if any elements left in left array
    while (i <= mid) t.push(v[i++]);
    // if any elements left in right array
    while (j <= h) t.push(v[j++]);

    // putting elements back in main array in descending order
    for (let k = 0, idx = l; idx <= h; idx++, k++)
        v[idx] = t[k];
}

function mergesort(v, ans, i, j) {
    if (i < j) {
        let mid = Math.floor((i + j) / 2);

        // calling mergesort for left half
        mergesort(v, ans, i, mid);

        // calling mergesort for right half
        mergesort(v, ans, mid + 1, j);

        // merging both halves and generating answer
        merge(v, ans, i, mid, j);
    }
}

function constructLowerArray(arr) {
    let n = arr.length;

    // inserting elements and corresponding index as pair
    let v = [];
    for (let i = 0; i < n; i++)
        v.push([arr[i], i]);

    // answer array for keeping count initialized by 0
    let ans = new Array(n).fill(0);

    // calling mergesort
    mergesort(v, ans, 0, n - 1);

    return ans;
}

// Utility function to print an array
function printArray(arr) {
    console.log(arr.join(" "));
}

// Driver code
let arr = [12, 1, 2, 3, 0, 11, 4];
let ans = constructLowerArray(arr);
printArray(ans);

Output
6 1 1 1 0 1 0 


Explore