Count subarrays for every array element in which they are the minimum

Given an array arr[] consisting of N integers, the task is to create an array brr[] of size N where brr[i] represents the count of subarrays in which arr[i] is the smallest element.

Examples:

Input: arr[] = {3, 2, 4}
Output: {1, 3, 1}
Explanation:
For arr[0], there is only one subarray in which 3 is the smallest({3}).
For arr[1], there are three such subarrays where 2 is the smallest({2}, {3, 2}, {2, 4}).
For arr[2], there is only one subarray in which 4 is the smallest({4}).

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

Naive Approach: The simplest approach is to generate all subarrays of the given array and for every array element arr[i], count the number of subarrays in which it is the smallest element.

Time Complexity: O(N3)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to find the boundary index for every element, up to which it is the smallest element. For each element let L and R be the boundary indices on the left and right side respectively up to which arr[i] is the minimum. Therefore, the count of all subarrays can be calculated by:

(L + R + 1)*(R + 1)

Follow the steps below to solve the problem:

1. Store all the indices of array elements in a Map.
2. Sort the array in increasing order.
3. Initialize an array boundary[].
4. Iterate over the sorted array arr[] and simply insert the index of that element using Binary Search. Suppose it got inserted at index i, then its left boundary is boundary[i – 1] and its right boundary is boundary[i + 1].
5. Now, using the above formula, find the number of subarrays and keep track of that count in the resultant array.
6. After completing the above steps, print all the counts stored in the resultant array.

Below is the implementation of the above approach:

C++14

 `// C++14 program for the above approach ` `#include ` `using` `namespace` `std; ` ` `  `// Function to find the boundary of every ` `// element within which it is minimum ` `int` `binaryInsert(vector<``int``> &boundary, ``int` `i) ` `{ ` `    ``int` `l = 0; ` `    ``int` `r = boundary.size() - 1; ` ` `  `    ``// Perform Binary Search ` `    ``while` `(l <= r) ` `    ``{ ` `         `  `        ``// Find mid m ` `        ``int` `m = (l + r) / 2; ` ` `  `        ``// Update l ` `        ``if` `(boundary[m] < i) ` `            ``l = m + 1; ` ` `  `        ``// Update r ` `        ``else` `            ``r = m - 1; ` `    ``} ` ` `  `    ``// Inserting the index ` `    ``boundary.insert(boundary.begin() + l, i); ` ` `  `    ``return` `l; ` `} ` ` `  `// Function to required count subarrays ` `vector<``int``> countingSubarray(vector<``int``> arr, ``int` `n) ` `{ ` `     `  `    ``// Stores the indices of element ` `    ``unordered_map<``int``, ``int``> index; ` ` `  `    ``for``(``int` `i = 0; i < n; i++) ` `        ``index[arr[i]] = i; ` ` `  `    ``vector<``int``> boundary = {-1, n}; ` `    ``sort(arr.begin(), arr.end()); ` ` `  `    ``// Initialize the output array ` `    ``vector<``int``> ans(n, 0); ` ` `  `    ``for``(``int` `num : arr) ` `    ``{ ` `        ``int` `i = binaryInsert(boundary, index[num]); ` ` `  `        ``// Left boundary, till the ` `        ``// element is smallest ` `        ``int` `l = boundary[i] - boundary[i - 1] - 1; ` ` `  `        ``// Right boundary, till the ` `        ``// element is smallest ` `        ``int` `r = boundary[i + 1] - boundary[i] - 1; ` ` `  `        ``// Calculate the number of subarrays ` `        ``// based on its boundary ` `        ``int` `cnt = l + r + l * r + 1; ` ` `  `        ``// Adding cnt to the ans ` `        ``ans[index[num]] += cnt; ` `    ``} ` `    ``return` `ans; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `N = 5; ` `     `  `    ``// Given array arr[] ` `    ``vector<``int``> arr = { 3, 2, 4, 1, 5 }; ` `     `  `    ``// Function call ` `    ``auto` `a = countingSubarray(arr, N); ` `     `  `    ``cout << ``"["``; ` `    ``int` `n = a.size() - 1; ` `    ``for``(``int` `i = 0; i < n; i++)  ` `        ``cout << a[i] << ``", "``; ` `         `  `    ``cout << a[n] << ``"]"``; ` `     `  `    ``return` `0; ` `} ` ` `  `// This code is contributed by mohit kumar 29 `

Java

 `// Java program for the above approach ` `import` `java.util.*; ` ` `  `class` `GFG{ ` `   `  `// Function to find the boundary of every  ` `// element within which it is minimum  ` `static` `int` `binaryInsert(ArrayList boundary,  ` `                        ``int` `i)  ` `{  ` `    ``int` `l = ``0``;  ` `    ``int` `r = boundary.size() - ``1``;  ` `   `  `    ``// Perform Binary Search  ` `    ``while` `(l <= r)  ` `    ``{  ` `       `  `        ``// Find mid m  ` `        ``int` `m = (l + r) / ``2``;  ` `   `  `        ``// Update l  ` `        ``if` `(boundary.get(m) < i)  ` `            ``l = m + ``1``;  ` `   `  `        ``// Update r  ` `        ``else` `            ``r = m - ``1``;  ` `    ``}  ` `   `  `    ``// Inserting the index  ` `    ``boundary.add(l, i);  ` `   `  `    ``return` `l;  ` `}  ` `   `  `// Function to required count subarrays  ` `static` `int``[] countingSubarray(``int``[] arr,  ` `                              ``int` `n)  ` `{  ` `   `  `    ``// Stores the indices of element  ` `    ``Map index = ``new` `HashMap<>();  ` `    ``for``(``int` `i = ``0``; i < n; i++)  ` `        ``index.put(arr[i], i);  ` `   `  `    ``ArrayList boundary = ``new` `ArrayList<>(); ` `    ``boundary.add(-``1``); ` `    ``boundary.add(n);  ` ` `  `    ``Arrays.sort(arr); ` ` `  `    ``// Initialize the output array  ` `    ``int``[] ans = ``new` `int``[n]; ` `   `  `    ``for``(``int` `num : arr)  ` `    ``{  ` `        ``int` `i = binaryInsert(boundary,  ` `                             ``index.get(num));  ` `   `  `        ``// Left boundary, till the  ` `        ``// element is smallest  ` `        ``int` `l = boundary.get(i) - ` `                ``boundary.get(i - ``1``) - ``1``;  ` `   `  `        ``// Right boundary, till the  ` `        ``// element is smallest  ` `        ``int` `r = boundary.get(i + ``1``) - ` `                ``boundary.get(i) - ``1``;  ` `   `  `        ``// Calculate the number of subarrays  ` `        ``// based on its boundary  ` `        ``int` `cnt = l + r + l * r + ``1``;  ` `   `  `        ``// Adding cnt to the ans  ` `        ``ans[index.get(num)] += cnt;  ` `    ``}  ` `    ``return` `ans;  ` `} ` `   `  `// Driver code ` `public` `static` `void` `main (String[] args)  ` `{ ` `    ``int` `N = ``5``;  ` `       `  `    ``// Given array arr[]  ` `    ``int``[] arr = { ``3``, ``2``, ``4``, ``1``, ``5` `};  ` `       `  `    ``// Function call  ` `    ``int``[] a = countingSubarray(arr, N);  ` `       `  `    ``System.out.print(``"["``);  ` `    ``int` `n = a.length - ``1``;  ` `    ``for``(``int` `i = ``0``; i < n; i++)   ` `        ``System.out.print(a[i] + ``", "``);  ` `           `  `    ``System.out.print(a[n] + ``"]"``);  ` `} ` `} ` ` `  `// This code is contributed by offbeat`

Python3

 `# Python3 program for the above approach ` ` `  `# Function to find the boundary of every ` `# element within which it is minimum ` `def` `binaryInsert(boundary, i): ` ` `  `    ``l ``=` `0` `    ``r ``=` `len``(boundary) ``-` `1` ` `  `    ``# Perform Binary Search ` `    ``while` `l <``=` `r: ` `         `  `        ``# Find mid m ` `        ``m ``=` `(l ``+` `r) ``/``/` `2` `         `  `        ``# Update l ` `        ``if` `boundary[m] < i: ` `            ``l ``=` `m ``+` `1` `             `  `        ``# Update r ` `        ``else``: ` `            ``r ``=` `m ``-` `1` ` `  `    ``# Inserting the index ` `    ``boundary.insert(l, i) ` ` `  `    ``return` `l ` ` `  `# Function to required count subarrays ` `def` `countingSubarray(arr, n): ` ` `  `    ``# Stores the indices of element ` `    ``index ``=` `{} ` ` `  `    ``for` `i ``in` `range``(n): ` `        ``index[arr[i]] ``=` `i ` ` `  `    ``boundary ``=` `[``-``1``, n] ` `    ``arr.sort() ` ` `  `    ``# Initialize the output array ` `    ``ans ``=` `[``0` `for` `i ``in` `range``(n)] ` ` `  `    ``for` `num ``in` `arr: ` `        ``i ``=` `binaryInsert(boundary, index[num]) ` ` `  `        ``# Left boundary, till the ` `        ``# element is smallest ` `        ``l ``=` `boundary[i] ``-` `boundary[i ``-` `1``] ``-` `1` ` `  `        ``# Right boundary, till the ` `        ``# element is smallest ` `        ``r ``=` `boundary[i ``+` `1``] ``-` `boundary[i] ``-` `1` ` `  `        ``# Calculate the number of subarrays ` `        ``# based on its boundary ` `        ``cnt ``=` `l ``+` `r ``+` `l ``*` `r ``+` `1` ` `  `        ``# Adding cnt to the ans ` `        ``ans[index[num]] ``+``=` `cnt ` ` `  `    ``return` `ans ` ` `  ` `  `# Driver Code ` ` `  `N ``=` `5` ` `  `# Given array arr[] ` `arr ``=` `[``3``, ``2``, ``4``, ``1``, ``5``] ` ` `  `# Function Call ` `print``(countingSubarray(arr, N)) `

C#

 `// C# program for  ` `// the above approach ` `using` `System; ` `using` `System.Collections; ` `using` `System.Collections.Generic; ` `class` `GFG{ ` `    `  `// Function to find the  ` `// boundary of every element  ` `// within which it is minimum  ` `static` `int` `binaryInsert(ArrayList boundary,  ` `                        ``int` `i)  ` `{  ` `  ``int` `l = 0;  ` `  ``int` `r = boundary.Count - 1;  ` ` `  `  ``// Perform Binary Search  ` `  ``while` `(l <= r)  ` `  ``{ ` `    ``// Find mid m  ` `    ``int` `m = (l + r) / 2;  ` ` `  `    ``// Update l  ` `    ``if` `((``int``)boundary[m] < i)  ` `      ``l = m + 1;  ` ` `  `    ``// Update r  ` `    ``else` `      ``r = m - 1;  ` `  ``}  ` ` `  `  ``// Inserting the index  ` `  ``boundary.Insert(l, i);  ` ` `  `  ``return` `l;  ` `}  ` `    `  `// Function to required count subarrays  ` `static` `int``[] countingSubarray(``int``[] arr,  ` `                              ``int` `n)  ` `{  ` `  ``// Stores the indices of element  ` `  ``Dictionary<``int``, ` `             ``int``> index = ``new` `Dictionary<``int``, ` `                                         ``int``>();  ` `  ``for``(``int` `i = 0; i < n; i++)  ` `    ``index[arr[i]] = i;  ` ` `  `  ``ArrayList boundary = ``new` `ArrayList(); ` `  ``boundary.Add(-1); ` `  ``boundary.Add(n);  ` `  ``Array.Sort(arr); ` ` `  `  ``// Initialize the output array  ` `  ``int``[] ans = ``new` `int``[n]; ` ` `  `  ``foreach``(``int` `num ``in` `arr)  ` `  ``{  ` `    ``int` `i = binaryInsert(boundary,  ` `                         ``index[num]);  ` ` `  `    ``// Left boundary, till the  ` `    ``// element is smallest  ` `    ``int` `l = (``int``)boundary[i] - ` `            ``(``int``)boundary[i - 1] - 1;  ` ` `  `    ``// Right boundary, till the  ` `    ``// element is smallest  ` `    ``int` `r = (``int``)boundary[i + 1] - ` `            ``(``int``)boundary[i] - 1;  ` ` `  `    ``// Calculate the number of   ` `    ``// subarrays based on its boundary  ` `    ``int` `cnt = l + r + l * r + 1;  ` ` `  `    ``// Adding cnt to the ans  ` `    ``ans[index[num]] += cnt;  ` `  ``}  ` `  ``return` `ans;  ` `} ` `    `  `// Driver code ` `public` `static` `void` `Main(``string``[] args)  ` `{ ` `    ``int` `N = 5;  ` `        `  `    ``// Given array arr[]  ` `    ``int``[] arr = {3, 2, 4, 1, 5};  ` `        `  `    ``// Function call  ` `    ``int``[] a = countingSubarray(arr, N);  ` `        `  `    ``Console.Write(``"["``);  ` `    ``int` `n = a.Length - 1;  ` `    ``for``(``int` `i = 0; i < n; i++)   ` `        ``Console.Write(a[i] + ``", "``);  ` `            `  `    ``Console.Write(a[n] + ``"]"``);  ` `} ` `} ` ` `  `// This code is contributed by Rutvik_56`

Output:

```[1, 4, 1, 8, 1]

```

Time Complexity: O(N log N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.