Count smaller elements on right side using Set in C++ STL
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).
- Traverse the array element from i=len-1 to 0 and insert every element in a set.
- Find the first element that is lower than A[i] using lower_bound function.
- Find the distance between above found element and the beginning of the set using distance function.
- Store the distance in another array , Let’s say CountSmaller[ ].
- 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; } |
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; } |
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.
Please Login to comment...