Open In App

Count smaller elements on right side using Set in C++ STL

Improve
Improve
Like Article
Like
Save
Share
Report

Write a function to count the number of smaller elements on the right of each element in an array. Given an unsorted array arr[] of distinct integers, construct another array countSmaller[] such that countSmaller[i] contains the count of smaller elements on right side of  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}

In this post an easy implementation of https://www.geeksforgeeks.org/count-smaller-elements-on-right-side/ is discussed.

Create an empty Set in C++ STL (Note that Set in C++ STL is implemented using Self Balancing Binary Search Tree). 

  1. Traverse the array element from i=len-1 to 0 and insert every element in a set.
  2. Find the first element that is lower than A[i] using lower_bound function.
  3. Find the distance between above found element and the beginning of the set using distance function.
  4. Store the distance in another array , Let’s say CountSmaller[ ].
  5. Print that array .

Implementation:

C++




// CPP program to find count of smaller
// elements on right side using set in C++
// STL.
#include <bits/stdc++.h>
using namespace std;
void countSmallerRight(int A[], int len)
{
    set<int> s;
    int countSmaller[len];
    for (int i = len - 1; i >= 0; i--) {
        s.insert(A[i]);
        auto it = s.lower_bound(A[i]);
        countSmaller[i] = distance(s.begin(), it);
    }
 
    for (int i = 0; i < len; i++)
        cout << countSmaller[i] << " ";
}
 
// Driver code
int main()
{
    int A[] = {12, 1, 2, 3, 0, 11, 4};
    int len = sizeof(A) / sizeof(int);
    countSmallerRight(A, len);
    return 0;
}


Output

6 1 1 1 0 1 0 

Time Complexity: Note that the above implementation takes worst-case time complexity O(n^2) as the worst case time complexity of distance function is O(n) but the above implementation is very simple and works better than the naive algorithm in the average case.
Space Complexity: O(n),The space complexity of the above code is O(n). This is because we are using a set which takes O(n) space to store the elements.

Above approach works for unique elements but for duplicate elements just replace Set with Multiset.

Efficient Approach: Using policy based data structures in C++ STL.

Maintain a policy-based data structure of pairs just to resolve duplicate issues.

  • We will travel the array from the end and every time we find the order_of_key of the current element to find the number of smaller elements to the right of it.
  • Then we will insert the current element into our policy-based data structure.  

Below is the implementation of the above approach:

C++




// C++ implementation of the above approach
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pbds                                               \
    tree<pair<int, int>, null_type, less<pair<int, int> >, \
         rb_tree_tag, tree_order_statistics_node_update>
using namespace __gnu_pbds;
using namespace std;
 
// Function to find number of smaller elements
// to the right of every element
void countSmallerRight(int arr[], int n)
{
    pbds s;
    // stores the answer
    vector<int> ans;
    for (int i = n - 1; i >= 0; i--) {
        if (i == n - 1) { // for the last element answer is
                          // zero
            ans.push_back(0);
        }
        else { // insert number of the smaller elements
            // to the right of current element into the ans
            ans.push_back(s.order_of_key({ arr[i], i }));
        }
        // insert current element
        s.insert({ arr[i], i });
    }
 
    reverse(ans.begin(), ans.end());
    for (auto x : ans)
        cout << x << " ";
}
 
// Driver Code
int main()
{
    int n = 7;
    int arr[] = { 12, 1, 2, 3, 0, 11, 4 };
    countSmallerRight(arr, n);
    return 0;
}


Output

6 1 1 1 0 1 0 

Time Complexity: O(N*LogN), where N is the number of elements in the given array. This is due to the fact that we are using a self-balancing binary search tree (PBDS) which has a time complexity of O(logN) for insertion and accessing the order statistic.

Space Complexity of the above algorithm is O(N) as we are using a self-balancing binary search tree to store the elements. We also use a vector to store the number of smaller elements to its right.



Last Updated : 05 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads