Count smaller elements on right side

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

Examples:

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

(Corner Cases)
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.


Method 1 (Simple)
Use two 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[].

C

filter_none

edit
close

play_arrow

link
brightness_4
code

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, 10, 5, 4, 2, 20, 6, 1, 0, 2};
  int n = sizeof(arr)/sizeof(arr[0]);
  int *low = (int *)malloc(sizeof(int)*n);
  constructLowerArray(arr, low, n);
  printArray(low, n);
  return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

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, 10, 5, 4, 2, 20, 6, 1, 0, 2};
        int n = arr.length;
        int low[] = new int[n];
        small.constructLowerArray(arr, low, n);
        small.printArray(low, n);
    }
}

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

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, 10, 5, 4, 2, 20, 6, 1, 0, 2]
n = len(arr)
low = [0]*n
constructLowerArray(arr, low, n)
printArray(low, n)
  
# This code is contributed by ApurvaRaj

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

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, 10, 5, 4, 
                            2, 20, 6, 1, 0, 2};
        int n = arr.Length;
        int []low = new int[n];
          
        constructLowerArray(arr, low, n);
        printArray(low, n);
    }
}
  
// This code is contributed by Sam007

chevron_right



Time Complexity: O(n^2)
Auxiliary Space: O(1)





Method 2 (Use Self Balancing BST)
A Self Balancing Binary Search Tree (AVL, Red Black,.. etc) can be used to get the solution in O(nLogn) time complexity. We can augment these trees so that every node N contains size the subtree rooted with N. We have used AVL tree in the following implementation.

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

Following is the C implementation.

filter_none

edit
close

play_arrow

link
brightness_4
code

#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[] = {10, 6, 15, 20, 30, 5, 7};
  int n = sizeof(arr)/sizeof(arr[0]);
  
  int *low = (int *)malloc(sizeof(int)*n);
  
  constructLowerArray(arr, low, n);
  
  printf("Following is the constructed smaller count array");
  printArray(low, n);
  return 0;
}

chevron_right


Output:

Following is the constructed smaller count array
3 1 2 2 2 0 0

Time Complexity: O(nLogn)
Auxiliary Space: O(n)



Method 3 (Using BST with 2 extra fields)
Another approach to solve the above problem would be to use a simple Binary Search Tree with 2 extra fields:
1) to hold the elements on the left side of a node
2) to store the frequency of element.
In this approach, we traverse the input array from the ending to the begging and add the elements into the BST.
While inserting the elements to the BST, we can compute the number of elements which are lesser elements simply by computing the sum of frequency of the element and the number of elements to the left side of current node, if we are moving to right side of the current node.
Once we place an element in it’s correct position, we can return it’s this sum value

A simple pythonic approach of above logic would be as follows:

Python

filter_none

edit
close

play_arrow

link
brightness_4
code

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 = [10, 6, 15, 20, 30, 5, 7]
    print(" ".join(list(map(str,constructArray(arr,n)))))
if __name__ == "__main__":
    main()
  
# Code Contributed by Tarun Gudipati

chevron_right



Output:

Following is the constructed smaller count array
3 1 2 2 2 0 0

Time Complexity: O(nLogn)
Auxiliary Space: O(n)

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.

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up