Skip to content
Related Articles

Related Articles

Count smaller elements on Right side

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 01 Nov, 2022
Improve Article
Save Article

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:  countSmaller[]  =  {6, 1, 1, 1, 0, 1, 0} 

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

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

We strongly recommend that you click here and practice it, before moving on to the solution.

Naive Approach:

Use nested loops. The outer loop picks all elements from left to right. The inner loop iterates through all the elements on right side of the picked element and updates countSmaller[].

Below is the implementation of the above idea.

C++




#include <iostream>
using namespace std;
 
void constructLowerArray(int arr[], int* countSmaller,
                         int n)
{
    int i, j;
 
    // Initialize all the counts in
    // countSmaller array as 0
    for (i = 0; i < n; i++)
        countSmaller[i] = 0;
 
    for (i = 0; i < n; i++) {
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[i])
                countSmaller[i]++;
        }
    }
}
 
// Utility function that prints
// out an array on a line
void printArray(int arr[], int size)
{
    int i;
    for (i = 0; i < size; i++)
        cout << arr[i] << " ";
 
    cout << "\n";
}
 
// Driver code
int main()
{
    int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int* low = (int*)malloc(sizeof(int) * n);
 
    constructLowerArray(arr, low, n);
    printArray(low, n);
 
    return 0;
}
 
// This code is contributed by Hemant Jain


C




void constructLowerArray(int arr[], int* countSmaller,
                         int n)
{
    int i, j;
 
    // initialize all the counts in countSmaller array as 0
    for (i = 0; i < n; i++)
        countSmaller[i] = 0;
 
    for (i = 0; i < n; i++) {
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[i])
                countSmaller[i]++;
        }
    }
}
 
/* Utility function that prints out an array on a line */
void printArray(int arr[], int size)
{
    int i;
    for (i = 0; i < size; i++)
        printf("%d ", arr[i]);
 
    printf("\n");
}
 
// Driver program to test above functions
int main()
{
    int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int* low = (int*)malloc(sizeof(int) * n);
 
    constructLowerArray(arr, low, n);
    printArray(low, n);
    return 0;
}


Java




class CountSmaller {
    void constructLowerArray(int arr[], int countSmaller[],
                             int n)
    {
        int i, j;
 
        // initialize all the counts in countSmaller array
        // as 0
        for (i = 0; i < n; i++)
            countSmaller[i] = 0;
 
        for (i = 0; i < n; i++) {
            for (j = i + 1; j < n; j++) {
                if (arr[j] < arr[i])
                    countSmaller[i]++;
            }
        }
    }
 
    /* Utility function that prints out an array on a line
     */
    void printArray(int arr[], int size)
    {
        int i;
        for (i = 0; i < size; i++)
            System.out.print(arr[i] + " ");
 
        System.out.println("");
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
        CountSmaller small = new CountSmaller();
        int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
        int n = arr.length;
        int low[] = new int[n];
        small.constructLowerArray(arr, low, n);
        small.printArray(low, n);
    }
}


Python3




def constructLowerArray(arr, countSmaller, n):
 
    # initialize all the counts in countSmaller array as 0
    for i in range(n):
        countSmaller[i] = 0
 
    for i in range(n):
        for j in range(i + 1, n):
            if (arr[j] < arr[i]):
                countSmaller[i] += 1
 
# Utility function that prints out an array on a line
 
 
def printArray(arr, size):
    for i in range(size):
        print(arr[i], end=" ")
    print()
 
 
# Driver code
arr = [12, 1, 2, 3, 0, 11, 4]
n = len(arr)
low = [0]*n
constructLowerArray(arr, low, n)
printArray(low, n)
 
# This code is contributed by ApurvaRaj


C#




using System;
 
class GFG {
 
    static void constructLowerArray(int[] arr,
                                    int[] countSmaller,
                                    int n)
    {
        int i, j;
 
        // initialize all the counts in
        // countSmaller array as 0
        for (i = 0; i < n; i++)
            countSmaller[i] = 0;
 
        for (i = 0; i < n; i++) {
            for (j = i + 1; j < n; j++) {
                if (arr[j] < arr[i])
                    countSmaller[i]++;
            }
        }
    }
 
    /* Utility function that prints out
    an array on a line */
    static void printArray(int[] arr, int size)
    {
        int i;
        for (i = 0; i < size; i++)
            Console.Write(arr[i] + " ");
 
        Console.WriteLine("");
    }
 
    // Driver function
    public static void Main()
    {
        int[] arr = new int[] { 12, 1, 2, 3, 0, 11, 4 };
        int n = arr.Length;
        int[] low = new int[n];
 
        constructLowerArray(arr, low, n);
        printArray(low, n);
    }
}
 
// This code is contributed by Sam007


Javascript




<script>
    function constructLowerArray(arr, countSmaller, n)
    {
        let i, j;
  
        // initialize all the counts in
        // countSmaller array as 0
        for (i = 0; i < n; i++)
            countSmaller[i] = 0;
  
        for (i = 0; i < n; i++)
        {
            for (j = i + 1; j < n; j++)
            {
                if (arr[j] < arr[i])
                    countSmaller[i]++;
            }
        }
    }
      
    /* Utility function that prints out
    an array on a line */
    function printArray(arr, size)
    {
        let i;
        for (i = 0; i < size; i++)
            document.write(arr[i] + " ");
  
        document.write("</br>");
    }
       
    let arr = [12, 1, 2, 3, 0, 11, 4];
    let n = arr.length;
    let low = new Array(n);
 
    constructLowerArray(arr, low, n);
    printArray(low, n);
         
</script>


Output

6 1 1 1 0 1 0 

Time Complexity: O(N2), Used nested loop for calculating every element in the array of size N.
Auxiliary Space: O(1)

Count smaller elements on the right side using Merge Sort:

The idea is to divide the array int to two halves just as we do in merge sort. And then while merging back we sort them in decreasing order and keep track of count the smaller elements.

Follow the steps below to solve the problem:

  • Declare an array of pair of int V and an array ans to keep track of count. Traverse the given array and insert all the elements and their corresponding index as a pair in this new array. We will call our merge sort function on this array. 
  • In the merge function, we declare two pointers i and j as usual to traverse our left and right array and merge them in descending order.
  • Now, as we traverse these two arrays, We know that all the elements that are present in right array are also on the right side (in the actual array) of the elements that are present in left array.
  • So, whenever we find a element in left array which is greater than the element in the right array( V[i].first > V[j].first ) we increase our count ans[ V[i].second ] += size of right array – j +1. Because our arrays are in decreasing order that means all the elements next to it are also smaller than V[i].first.
  • After increasing the count we just simply do our sorting in decreasing and move our pointers ahead.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
void merge(vector<pair<int, int> >& v, vector<int>& ans,
           int l, int mid, int h)
{
 
    vector<pair<int, int> >
        t; // temporary array for merging both halves
    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, i = l; i <= h; i++, k++)
        v[i] = 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(int* arr, int n)
{
 
    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;
}
 
// Driver Code Starts.
 
int main()
{
    int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    auto ans = constructLowerArray(arr, n);
    for (auto x : ans) {
        cout << x << " ";
    }
    cout << "\n";
    return 0;
}
// Driver code ends.
 
// This code is contributed by Manjeet Singh


Output

6 1 1 1 0 1 0 

Time Complexity: O(N * log N), Used for Merge Sort.
Auxiliary Space: O(N), Space used to store the pair values in a different array.

Count smaller elements on the right side using Self-Balancing BST:

The idea is to use a Self Balancing Binary Search Tree (AVL, Red Black,.. etc) can be used to get the solution in O(N log N) time complexity. We can augment these trees so that every node N contains the size of the subtree rooted with N.

Follow the steps below to solve the problem:

  • We traverse the array from right to left and insert all elements in an AVL tree. 
  • While inserting a new key in an AVL tree, first compare the key with the root. If the key is greater than the root, then it is greater than all the nodes in the left subtree of the root. 
  • So we add the size of the left subtree to the count of smaller elements for the key being inserted. 
  • We recursively follow the same approach for all nodes down the root.

Below is the implementation of the above approach.

C++




#include <iostream>
using namespace std;
 
#include <stdio.h>
#include <stdlib.h>
 
// An AVL tree node
struct node {
    int key;
    struct node* left;
    struct node* right;
    int height;
 
    // size of the tree rooted
    // with this node
    int size;
};
 
// A utility function to get
// maximum of two integers
int max(int a, int b);
 
// A utility function to get
// height of the tree rooted with N
int height(struct node* N)
{
    if (N == NULL)
        return 0;
 
    return N->height;
}
 
// A utility function to size
// of the tree of rooted with N
int size(struct node* N)
{
    if (N == NULL)
        return 0;
 
    return N->size;
}
 
// A utility function to
// get maximum of two integers
int max(int a, int b) { return (a > b) ? a : b; }
 
// Helper function that allocates a
// new node with the given key and
// NULL left and right pointers.
struct node* newNode(int key)
{
    struct node* node
        = (struct node*)malloc(sizeof(struct node));
    node->key = key;
    node->left = NULL;
    node->right = NULL;
 
    // New node is initially added at leaf
    node->height = 1;
    node->size = 1;
    return (node);
}
 
// A utility function to right rotate
// subtree rooted with y
struct node* rightRotate(struct node* y)
{
    struct node* x = y->left;
    struct node* T2 = x->right;
 
    // Perform rotation
    x->right = y;
    y->left = T2;
 
    // Update heights
    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;
 
    // Update sizes
    y->size = size(y->left) + size(y->right) + 1;
    x->size = size(x->left) + size(x->right) + 1;
 
    // Return new root
    return x;
}
 
// A utility function to left rotate
// subtree rooted with x
struct node* leftRotate(struct node* x)
{
    struct node* y = x->right;
    struct node* T2 = y->left;
 
    // Perform rotation
    y->left = x;
    x->right = T2;
 
    //  Update heights
    x->height = max(height(x->left), height(x->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;
 
    // Update sizes
    x->size = size(x->left) + size(x->right) + 1;
    y->size = size(y->left) + size(y->right) + 1;
 
    // Return new root
    return y;
}
 
// Get Balance factor of node N
int getBalance(struct node* N)
{
    if (N == NULL)
        return 0;
 
    return height(N->left) - height(N->right);
}
 
// Inserts a new key to the tree rotted with
// node. Also, updates *count to contain count
// of smaller elements for the new key
struct node* insert(struct node* node, int key, int* count)
{
    // 1. Perform the normal BST rotation
    if (node == NULL)
        return (newNode(key));
 
    if (key < node->key)
        node->left = insert(node->left, key, count);
    else {
        node->right = insert(node->right, key, count);
 
        // UPDATE COUNT OF SMALLER ELEMENTS FOR KEY
        *count = *count + size(node->left) + 1;
    }
 
    // 2.Update height and size of this ancestor node
    node->height
        = max(height(node->left), height(node->right)) + 1;
    node->size = size(node->left) + size(node->right) + 1;
 
    // 3. Get the balance factor of this
    // ancestor node to check whether this
    // node became unbalanced
    int balance = getBalance(node);
 
    // If this node becomes unbalanced,
    // then there are 4 cases
 
    // Left Left Case
    if (balance > 1 && key < node->left->key)
        return rightRotate(node);
 
    // Right Right Case
    if (balance < -1 && key > node->right->key)
        return leftRotate(node);
 
    // Left Right Case
    if (balance > 1 && key > node->left->key) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }
 
    // Right Left Case
    if (balance < -1 && key < node->right->key) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }
 
    // Return the (unchanged) node pointer
    return node;
}
 
// The following function updates the
// countSmaller array to contain count of
// smaller elements on right side.
void constructLowerArray(int arr[], int countSmaller[],
                         int n)
{
    int i, j;
    struct node* root = NULL;
 
    // Initialize all the counts in
    // countSmaller array as 0
    for (i = 0; i < n; i++)
        countSmaller[i] = 0;
 
    // Starting from rightmost element,
    // insert all elements one by one in
    // an AVL tree and get the count of
    // smaller elements
    for (i = n - 1; i >= 0; i--) {
        root = insert(root, arr[i], &countSmaller[i]);
    }
}
 
// Utility function that prints out an
// array on a line
void printArray(int arr[], int size)
{
    int i;
    cout << "\n";
 
    for (i = 0; i < size; i++)
        cout << arr[i] << " ";
}
 
// Driver code
int main()
{
    int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int* low = (int*)malloc(sizeof(int) * n);
 
    constructLowerArray(arr, low, n);
 
    printArray(low, n);
 
    return 0;
}
 
// This code is contributed by Hemant Jain


C




#include <stdio.h>
#include <stdlib.h>
 
// An AVL tree node
struct node {
    int key;
    struct node* left;
    struct node* right;
    int height;
    int size; // size of the tree rooted with this node
};
 
// A utility function to get maximum of two integers
int max(int a, int b);
 
// A utility function to get height of the tree rooted with
// N
int height(struct node* N)
{
    if (N == NULL)
        return 0;
    return N->height;
}
 
// A utility function to size of the tree of rooted with N
int size(struct node* N)
{
    if (N == NULL)
        return 0;
    return N->size;
}
 
// A utility function to get maximum of two integers
int max(int a, int b) { return (a > b) ? a : b; }
 
/* Helper function that allocates a new node with the given
   key and NULL left and right pointers. */
struct node* newNode(int key)
{
    struct node* node
        = (struct node*)malloc(sizeof(struct node));
    node->key = key;
    node->left = NULL;
    node->right = NULL;
    node->height = 1; // new node is initially added at leaf
    node->size = 1;
    return (node);
}
 
// A utility function to right rotate subtree rooted with y
struct node* rightRotate(struct node* y)
{
    struct node* x = y->left;
    struct node* T2 = x->right;
 
    // Perform rotation
    x->right = y;
    y->left = T2;
 
    // Update heights
    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;
 
    // Update sizes
    y->size = size(y->left) + size(y->right) + 1;
    x->size = size(x->left) + size(x->right) + 1;
 
    // Return new root
    return x;
}
 
// A utility function to left rotate subtree rooted with x
struct node* leftRotate(struct node* x)
{
    struct node* y = x->right;
    struct node* T2 = y->left;
 
    // Perform rotation
    y->left = x;
    x->right = T2;
 
    //  Update heights
    x->height = max(height(x->left), height(x->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;
 
    // Update sizes
    x->size = size(x->left) + size(x->right) + 1;
    y->size = size(y->left) + size(y->right) + 1;
 
    // Return new root
    return y;
}
 
// Get Balance factor of node N
int getBalance(struct node* N)
{
    if (N == NULL)
        return 0;
    return height(N->left) - height(N->right);
}
 
// Inserts a new key to the tree rotted with node. Also,
// updates *count to contain count of smaller elements for
// the new key
struct node* insert(struct node* node, int key, int* count)
{
    /* 1.  Perform the normal BST rotation */
    if (node == NULL)
        return (newNode(key));
 
    if (key < node->key)
        node->left = insert(node->left, key, count);
    else {
        node->right = insert(node->right, key, count);
 
        // UPDATE COUNT OF SMALLER ELEMENTS FOR KEY
        *count = *count + size(node->left) + 1;
    }
 
    /* 2. Update height and size of this ancestor node */
    node->height
        = max(height(node->left), height(node->right)) + 1;
    node->size = size(node->left) + size(node->right) + 1;
 
    /* 3. Get the balance factor of this ancestor node to
       check whether this node became unbalanced */
    int balance = getBalance(node);
 
    // If this node becomes unbalanced, then there are 4
    // cases
 
    // Left Left Case
    if (balance > 1 && key < node->left->key)
        return rightRotate(node);
 
    // Right Right Case
    if (balance < -1 && key > node->right->key)
        return leftRotate(node);
 
    // Left Right Case
    if (balance > 1 && key > node->left->key) {
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }
 
    // Right Left Case
    if (balance < -1 && key < node->right->key) {
        node->right = rightRotate(node->right);
        return leftRotate(node);
    }
 
    /* return the (unchanged) node pointer */
    return node;
}
 
// The following function updates the countSmaller array to
// contain count of smaller elements on right side.
void constructLowerArray(int arr[], int countSmaller[],
                         int n)
{
    int i, j;
    struct node* root = NULL;
 
    // initialize all the counts in countSmaller array as 0
    for (i = 0; i < n; i++)
        countSmaller[i] = 0;
 
    // Starting from rightmost element, insert all elements
    // one by one in an AVL tree and get the count of
    // smaller elements
    for (i = n - 1; i >= 0; i--) {
        root = insert(root, arr[i], &countSmaller[i]);
    }
}
 
/* Utility function that prints out an array on a line */
void printArray(int arr[], int size)
{
    int i;
    printf("\n");
    for (i = 0; i < size; i++)
        printf("%d ", arr[i]);
}
 
// Driver program to test above functions
int main()
{
    int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int* low = (int*)malloc(sizeof(int) * n);
 
    constructLowerArray(arr, low, n);
 
    printArray(low, n);
    return 0;
}


Java




import java.util.*;
 
class GFG {
 
    // An AVL tree node
    static class node {
        int key;
        node left;
        node right;
        int height;
 
        // size of the tree rooted
        // with this node
        int size;
    };
    static int[] countSmaller;
    static int count;
 
    // A utility function to get
    // height of the tree rooted with N
    static int height(node N)
    {
        if (N == null)
            return 0;
 
        return N.height;
    }
 
    // A utility function to size
    // of the tree of rooted with N
    static int size(node N)
    {
        if (N == null)
            return 0;
 
        return N.size;
    }
 
    // A utility function to
    // get maximum of two integers
    static int max(int a, int b) { return (a > b) ? a : b; }
 
    // Helper function that allocates a
    // new node with the given key and
    // null left and right pointers.
    static node newNode(int key)
    {
        node node = new node();
        node.key = key;
        node.left = null;
        node.right = null;
 
        // New node is initially added at leaf
        node.height = 1;
        node.size = 1;
        return (node);
    }
 
    // A utility function to right rotate
    // subtree rooted with y
    static node rightRotate(node y)
    {
        node x = y.left;
        node T2 = x.right;
 
        // Perform rotation
        x.right = y;
        y.left = T2;
 
        // Update heights
        y.height
            = Math.max(height(y.left), height(y.right)) + 1;
        x.height
            = Math.max(height(x.left), height(x.right)) + 1;
 
        // Update sizes
        y.size = size(y.left) + size(y.right) + 1;
        x.size = size(x.left) + size(x.right) + 1;
 
        // Return new root
        return x;
    }
 
    // A utility function to left rotate
    // subtree rooted with x
    static node leftRotate(node x)
    {
        node y = x.right;
        node T2 = y.left;
 
        // Perform rotation
        y.left = x;
        x.right = T2;
 
        //  Update heights
        x.height
            = Math.max(height(x.left), height(x.right)) + 1;
        y.height
            = Math.max(height(y.left), height(y.right)) + 1;
 
        // Update sizes
        x.size = size(x.left) + size(x.right) + 1;
        y.size = size(y.left) + size(y.right) + 1;
 
        // Return new root
        return y;
    }
 
    // Get Balance factor of node N
    static int getBalance(node N)
    {
        if (N == null)
            return 0;
 
        return height(N.left) - height(N.right);
    }
 
    // Inserts a new key to the tree rotted with
    // node. Also, updates *count to contain count
    // of smaller elements for the new key
    static node insert(node node, int key, int count)
    {
        // 1. Perform the normal BST rotation
        if (node == null)
            return (newNode(key));
 
        if (key < node.key)
            node.left = insert(node.left, key, count);
        else {
            node.right = insert(node.right, key, count);
 
            // UPDATE COUNT OF SMALLER ELEMENTS FOR KEY
            countSmaller[count]
                = countSmaller[count] + size(node.left) + 1;
        }
 
        // 2.Update height and size of this ancestor node
        node.height = Math.max(height(node.left),
                               height(node.right))
                      + 1;
        node.size = size(node.left) + size(node.right) + 1;
 
        // 3. Get the balance factor of this
        // ancestor node to check whether this
        // node became unbalanced
        int balance = getBalance(node);
 
        // If this node becomes unbalanced,
        // then there are 4 cases
 
        // Left Left Case
        if (balance > 1 && key < node.left.key)
            return rightRotate(node);
 
        // Right Right Case
        if (balance < -1 && key > node.right.key)
            return leftRotate(node);
 
        // Left Right Case
        if (balance > 1 && key > node.left.key) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }
 
        // Right Left Case
        if (balance < -1 && key < node.right.key) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }
 
        // Return the (unchanged) node pointer
        return node;
    }
 
    // The following function updates the
    // countSmaller array to contain count of
    // smaller elements on right side.
    static void constructLowerArray(int arr[], int n)
    {
        int i, j;
        node root = null;
 
        // Initialize all the counts in
        // countSmaller array as 0
        for (i = 0; i < n; i++)
            countSmaller[i] = 0;
 
        // Starting from rightmost element,
        // insert all elements one by one in
        // an AVL tree and get the count of
        // smaller elements
        for (i = n - 1; i >= 0; i--) {
            root = insert(root, arr[i], i);
        }
    }
 
    // Utility function that prints out an
    // array on a line
    static void printArray(int arr[], int size)
    {
        int i;
        System.out.print("\n");
 
        for (i = 0; i < size; i++)
            System.out.print(arr[i] + " ");
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
        int n = arr.length;
 
        countSmaller = new int[n];
 
        constructLowerArray(arr, n);
 
        printArray(countSmaller, n);
    }
}
 
// This code is contributed by Rajput-Ji


Python3




import math
 
 
class GFG:
    # An AVL tree node
    class node:
        key = 0
        left = None
        right = None
        height = 0
        # size of the tree rooted
        # with this node
        size = 0
    countSmaller = None
    count = 0
    # A utility function to get
    # height of the tree rooted with N
 
    @staticmethod
    def height(N):
        if (N == None):
            return 0
        return N.height
    # A utility function to size
    # of the tree of rooted with N
 
    @staticmethod
    def size(N):
        if (N == None):
            return 0
        return N.size
    # A utility function to
    # get maximum of two integers
 
    @staticmethod
    def max(a,  b):
        return a if (a > b) else b
    # Helper function that allocates a
    # new node with the given key and
    # null left and right pointers.
 
    @staticmethod
    def newNode(key):
        node = GFG.node()
        node.key = key
        node.left = None
        node.right = None
        # New node is initially added at leaf
        node.height = 1
        node.size = 1
        return (node)
    # A utility function to right rotate
    # subtree rooted with y
 
    @staticmethod
    def rightRotate(y):
        x = y.left
        T2 = x.right
        # Perform rotation
        x.right = y
        y.left = T2
        # Update heights
        y.height = max(GFG.height(y.left), GFG.height(y.right)) + 1
        x.height = max(GFG.height(x.left), GFG.height(x.right)) + 1
        # Update sizes
        y.size = GFG.size(y.left) + GFG.size(y.right) + 1
        x.size = GFG.size(x.left) + GFG.size(x.right) + 1
        # Return new root
        return x
    # A utility function to left rotate
    # subtree rooted with x
 
    @staticmethod
    def leftRotate(x):
        y = x.right
        T2 = y.left
        # Perform rotation
        y.left = x
        x.right = T2
        #  Update heights
        x.height = max(GFG.height(x.left), GFG.height(x.right)) + 1
        y.height = max(GFG.height(y.left), GFG.height(y.right)) + 1
        # Update sizes
        x.size = GFG.size(x.left) + GFG.size(x.right) + 1
        y.size = GFG.size(y.left) + GFG.size(y.right) + 1
        # Return new root
        return y
    # Get Balance factor of node N
 
    @staticmethod
    def getBalance(N):
        if (N == None):
            return 0
        return GFG.height(N.left) - GFG.height(N.right)
    # Inserts a new key to the tree rotted with
    # node. Also, updates *count to contain count
    # of smaller elements for the new key
 
    @staticmethod
    def insert(node,  key,  count):
        # 1. Perform the normal BST rotation
        if (node == None):
            return (GFG.newNode(key))
        if (key < node.key):
            node.left = GFG.insert(node.left, key, count)
        else:
            node.right = GFG.insert(node.right, key, count)
            # UPDATE COUNT OF SMALLER ELEMENTS FOR KEY
            GFG.countSmaller[count] = GFG.countSmaller[count] + \
                GFG.size(node.left) + 1
        # 2.Update height and size of this ancestor node
        node.height = max(GFG.height(node.left), GFG.height(node.right)) + 1
        node.size = GFG.size(node.left) + GFG.size(node.right) + 1
        # 3. Get the balance factor of this
        # ancestor node to check whether this
        # node became unbalanced
        balance = GFG.getBalance(node)
        # If this node becomes unbalanced,
        # then there are 4 cases
        # Left Left Case
        if (balance > 1 and key < node.left.key):
            return GFG.rightRotate(node)
        # Right Right Case
        if (balance < -1 and key > node.right.key):
            return GFG.leftRotate(node)
        # Left Right Case
        if (balance > 1 and key > node.left.key):
            node.left = GFG.leftRotate(node.left)
            return GFG.rightRotate(node)
        # Right Left Case
        if (balance < -1 and key < node.right.key):
            node.right = GFG.rightRotate(node.right)
            return GFG.leftRotate(node)
        # Return the (unchanged) node pointer
        return node
    # The following function updates the
    # countSmaller array to contain count of
    # smaller elements on right side.
 
    @staticmethod
    def constructLowerArray(arr,  n):
        i = 0
        j = 0
        root = None
        # Initialize all the counts in
        # countSmaller array as 0
        i = 0
        while (i < n):
            GFG.countSmaller[i] = 0
            i += 1
        # Starting from rightmost element,
        # insert all elements one by one in
        # an AVL tree and get the count of
        # smaller elements
        i = n - 1
        while (i >= 0):
            root = GFG.insert(root, arr[i], i)
            i -= 1
    # Utility function that prints out an
    # array on a line
 
    @staticmethod
    def printArray(arr,  size):
        i = 0
        print("\n", end="")
        i = 0
        while (i < size):
            print(str(arr[i]) + " ", end="")
            i += 1
    # Driver code
 
    @staticmethod
    def main(args):
        arr = [12, 1, 2, 3, 0, 11, 4]
        n = len(arr)
        GFG.countSmaller = [0] * (n)
        GFG.constructLowerArray(arr, n)
        GFG.printArray(GFG.countSmaller, n)
 
 
if __name__ == "__main__":
    GFG.main([])


C#




using System;
public class GFG {
 
    // An AVL tree node
    public class node {
        public int key;
        public node left;
        public node right;
        public int height;
 
        // size of the tree rooted
        // with this node
        public int size;
    };
 
    static int[] countSmaller;
    static int count;
 
    // A utility function to get
    // height of the tree rooted with N
    static int height(node N)
    {
        if (N == null)
            return 0;
 
        return N.height;
    }
 
    // A utility function to size
    // of the tree of rooted with N
    static int size(node N)
    {
        if (N == null)
            return 0;
 
        return N.size;
    }
 
    // A utility function to
    // get maximum of two integers
    static int max(int a, int b) { return (a > b) ? a : b; }
 
    // Helper function that allocates a
    // new node with the given key and
    // null left and right pointers.
    static node newNode(int key)
    {
        node node = new node();
        node.key = key;
        node.left = null;
        node.right = null;
 
        // New node is initially added at leaf
        node.height = 1;
        node.size = 1;
        return (node);
    }
 
    // A utility function to right rotate
    // subtree rooted with y
    static node rightRotate(node y)
    {
        node x = y.left;
        node T2 = x.right;
 
        // Perform rotation
        x.right = y;
        y.left = T2;
 
        // Update heights
        y.height
            = Math.Max(height(y.left), height(y.right)) + 1;
        x.height
            = Math.Max(height(x.left), height(x.right)) + 1;
 
        // Update sizes
        y.size = size(y.left) + size(y.right) + 1;
        x.size = size(x.left) + size(x.right) + 1;
 
        // Return new root
        return x;
    }
 
    // A utility function to left rotate
    // subtree rooted with x
    static node leftRotate(node x)
    {
        node y = x.right;
        node T2 = y.left;
 
        // Perform rotation
        y.left = x;
        x.right = T2;
 
        // Update heights
        x.height
            = Math.Max(height(x.left), height(x.right)) + 1;
        y.height
            = Math.Max(height(y.left), height(y.right)) + 1;
 
        // Update sizes
        x.size = size(x.left) + size(x.right) + 1;
        y.size = size(y.left) + size(y.right) + 1;
 
        // Return new root
        return y;
    }
 
    // Get Balance factor of node N
    static int getBalance(node N)
    {
        if (N == null)
            return 0;
 
        return height(N.left) - height(N.right);
    }
 
    // Inserts a new key to the tree rotted with
    // node. Also, updates *count to contain count
    // of smaller elements for the new key
    static node insert(node node, int key, int count)
    {
        // 1. Perform the normal BST rotation
        if (node == null)
            return (newNode(key));
 
        if (key < node.key)
            node.left = insert(node.left, key, count);
        else {
            node.right = insert(node.right, key, count);
 
            // UPDATE COUNT OF SMALLER ELEMENTS FOR KEY
            countSmaller[count]
                = countSmaller[count] + size(node.left) + 1;
        }
 
        // 2.Update height and size of this ancestor node
        node.height = Math.Max(height(node.left),
                               height(node.right))
                      + 1;
        node.size = size(node.left) + size(node.right) + 1;
 
        // 3. Get the balance factor of this
        // ancestor node to check whether this
        // node became unbalanced
        int balance = getBalance(node);
 
        // If this node becomes unbalanced,
        // then there are 4 cases
 
        // Left Left Case
        if (balance > 1 && key < node.left.key)
            return rightRotate(node);
 
        // Right Right Case
        if (balance < -1 && key > node.right.key)
            return leftRotate(node);
 
        // Left Right Case
        if (balance > 1 && key > node.left.key) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }
 
        // Right Left Case
        if (balance < -1 && key < node.right.key) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }
 
        // Return the (unchanged) node pointer
        return node;
    }
 
    // The following function updates the
    // countSmaller array to contain count of
    // smaller elements on right side.
    static void constructLowerArray(int[] arr, int n)
    {
        int i, j;
        node root = null;
 
        // Initialize all the counts in
        // countSmaller array as 0
        for (i = 0; i < n; i++)
            countSmaller[i] = 0;
 
        // Starting from rightmost element,
        // insert all elements one by one in
        // an AVL tree and get the count of
        // smaller elements
        for (i = n - 1; i >= 0; i--) {
            root = insert(root, arr[i], i);
        }
    }
 
    // Utility function that prints out an
    // array on a line
    static void printArray(int[] arr, int size)
    {
        int i;
        Console.Write("\n");
 
        for (i = 0; i < size; i++)
            Console.Write(arr[i] + " ");
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 12, 1, 2, 3, 0, 11, 4 };
        int n = arr.Length;
 
        countSmaller = new int[n];
 
        constructLowerArray(arr, n);
 
        printArray(countSmaller, n);
    }
}
 
// This code is contributed by Rajput-Ji


Output

6 1 1 1 0 1 0 

Time Complexity: O(N * log N), Used self-balancing bst which takes logN time for every operation.
Auxiliary Space: O(N), Space used to store the nodes

Count smaller elements on the right side using BST with 2 extra fields:

The idea is to use a simple Binary Search Tree with 2 extra fields: 

  • to hold the elements on the left side of a node 
  • to store the frequency of element. 

Follow the steps below to solve the problem:

  • Traverse the input array from the ending to the begging and add the elements into the BST. 
  • While inserting the elements into the BST, compute the number of elements that are lesser elements simply by computing the sum of the frequency of the element
  • And the number of elements to the left side of the current node
  • if we are moving to the right side of the current node. 

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// BST node structure
class Node {
 
public:
    int val;
    int count;
    Node* left;
    Node* right;
 
    // Constructor
    Node(int num1, int num2)
    {
        this->val = num1;
        this->count = num2;
        this->left = this->right = NULL;
    }
};
 
// Function to addNode and find the smaller
// elements on the right side
int addNode(Node*& root, int value, int countSmaller)
{
 
    // Base case
    if (root == NULL) {
        root = new Node(value, 0);
        return countSmaller;
    }
    if (root->val < value) {
        return root->count
               + addNode(root->right, value,
                         countSmaller + 1);
    }
    else {
        root->count++;
        return addNode(root->left, value, countSmaller);
    }
}
 
// Driver code
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int data[] = { 12, 1, 2, 3, 0, 11, 4 };
    int size = sizeof(data) / sizeof(data[0]);
    int ans[size] = { 0 };
 
    Node* root = NULL;
 
    for (int i = size - 1; i >= 0; i--) {
        ans[i] = addNode(root, data[i], 0);
    }
 
    for (int i = 0; i < size; i++)
        cout << ans[i] << " ";
 
    return 0;
}
 
// This code is contributed by divyanshu gupta


Python3




class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
 
        # denotes number of times (frequency)
        # an element has occurred.
        self.elecount = 1
 
        # denotes the number of nodes on left
        # side of the node encountered so far.
        self.lcount = 0
 
 
class Tree:
    def __init__(self, root):
        self.root = root
 
    def insert(self, node):
        """This function helps to place an element at
            its correct position in the BST and returns
            the count of elements which are smaller than
            the elements which are already inserted into the BST.
        """
        curr = self.root
        cnt = 0
        while curr != None:
            prev = curr
            if node.val > curr.val:
 
                # This step computes the number of elements
                # which are less than the current Node.
                cnt += (curr.elecount+curr.lcount)
                curr = curr.right
            elif node.val < curr.val:
                curr.lcount += 1
                curr = curr.left
            else:
                prev = curr
                prev.elecount += 1
                break
        if prev.val > node.val:
            prev.left = node
        elif prev.val < node.val:
            prev.right = node
        else:
            return cnt+prev.lcount
        return cnt
 
 
def constructArray(arr, n):
    t = Tree(Node(arr[-1]))
    ans = [0]
    for i in range(n-2, -1, -1):
        ans.append(t.insert(Node(arr[i])))
    return reversed(ans)
 
# Driver function for above code
 
 
def main():
    n = 7
    arr = [12, 1, 2, 3, 0, 11, 4]
    print(" ".join(list(map(str, constructArray(arr, n)))))
 
 
if __name__ == "__main__":
    main()
 
# Code Contributed by Tarun Gudipati


C#




// C# program to implement above logic
using System;
 
// BST node structure
class GFG {
    class Node {
        public int val;
        public int count;
        public Node left;
        public Node right;
 
        // Constructor
        public Node(int num1, int num2)
        {
            val = num1;
            count = num2;
            left = right = null;
        }
    }
    static Node root = null;
 
    // Function to addNode and find the smaller
    // elements on the right side
    int addNode(ref Node root, int value, int countSmaller)
    {
        // Base case
        if (root == null) {
            root = new Node(value, 0);
            return countSmaller;
        }
        if (root.val < value) {
            return root.count
                + addNode(ref root.right, value,
                          countSmaller + 1);
        }
        else {
            root.count += 1;
            return addNode(ref root.left, value,
                           countSmaller);
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        GFG tree = new GFG();
        int[] data = { 12, 1, 2, 3, 0, 11, 4 };
        int size = data.Length;
        int[] ans = new int[size];
 
        for (int i = size - 1; i >= 0; i--) {
            ans[i] = tree.addNode(ref root, data[i], 0);
        }
        for (int i = 0; i < size; i++)
            Console.Write(ans[i] + " ");
    }
}
 
// This code is contributed by Abhijeet Kumar(abhijeet19403)


Output

6 1 1 1 0 1 0 

Time Complexity: O(N2) as adding step can take O(N) time.
Auxiliary Space: O(N), Space used to store the elements.

 Count smaller elements on right side using Set in C++ STL
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!