Count of subarrays for each Array element in which arr[i] is first and least
Last Updated :
04 Apr, 2022
Given an array arr[], the task is to find the count of subarrays starting from the current element that has a minimum element as the current element itself.
Examples:
Input: arr[] = {2, 4, 2, 1, 3}
Output: {3, 1, 1, 2, 1}
Explanation: For the first element we can form 3 valid subarrays with the given condition
- 2 -> {2} , {2,4} , {2,4,2} = 3 subarrays and so on
- 4 -> {4} = 1 subarray
- 2 -> {2} = 1 subarray
- 1 -> {1} , {1, 3} = 2 subarrays
- 3 -> {3} = 1 subarray
Input: arr[] = {1, 4, 2, 5, 3}
Output: {5, 1, 3, 1, 1}
Naive Solution: The naive approach revolves around the idea that:
- If smaller element is not found then count of subarrays = length of array – current index
- If element is found then count of subarrays = index of smaller element – current index
The task can be solved using 2 loops. The outer loop picks all the elements one by one. The inner loop looks for the first smaller element for the element picked by the outer loop. If a smaller element is found then the index of that element – current index is stored as next, otherwise, the length – current index is stored.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > countOfSubArray(vector< int > arr)
{
int next, i, j;
int n = arr.size();
vector< int > ans;
for (i = 0; i < n; i++) {
bool flag = false ;
next = n - i;
for (j = i + 1; j < n; j++) {
if (arr[i] > arr[j]) {
next = j - i;
ans.push_back(next);
flag = true ;
break ;
}
}
if (flag == false ) {
ans.push_back(next);
}
}
return ans;
}
int main()
{
vector< int > arr{ 1, 4, 2, 5, 3 };
vector< int > ans = countOfSubArray(arr);
for ( int i = 0; i < ans.size(); i++) {
cout << ans[i] << " " ;
}
return 0;
}
|
Java
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> countOfSubArray( int [] arr) {
int next, i, j;
int n = arr.length;
ArrayList<Integer> ans = new ArrayList<Integer>();
for (i = 0 ; i < n; i++) {
boolean flag = false ;
next = n - i;
for (j = i + 1 ; j < n; j++) {
if (arr[i] > arr[j]) {
next = j - i;
ans.add(next);
flag = true ;
break ;
}
}
if (flag == false ) {
ans.add(next);
}
}
return ans;
}
public static void main(String args[])
{
int [] arr = { 1 , 4 , 2 , 5 , 3 };
ArrayList<Integer> ans = countOfSubArray(arr);
for ( int i = 0 ; i < ans.size(); i++) {
System.out.print(ans.get(i) + " " );
}
}
}
|
Python3
def countOfSubArray(arr):
n = len (arr)
ans = []
for i in range (n):
flag = 0
next = n - i
for j in range (i + 1 , n):
if arr[i] > arr[j]:
next = j - i
ans.append( next )
flag = 1
break
if flag = = 0 :
ans.append( next )
return ans
arr = [ 1 , 4 , 2 , 5 , 3 ]
ans = countOfSubArray(arr)
for i in range ( len (ans)):
print (ans[i], end = " " )
|
C#
using System;
using System.Collections.Generic;
class GFG {
static List< int > countOfSubArray( int [] arr)
{
int next, i, j;
int n = arr.Length;
List< int > ans = new List< int >();
for (i = 0; i < n; i++) {
bool flag = false ;
next = n - i;
for (j = i + 1; j < n; j++) {
if (arr[i] > arr[j]) {
next = j - i;
ans.Add(next);
flag = true ;
break ;
}
}
if (flag == false ) {
ans.Add(next);
}
}
return ans;
}
public static void Main()
{
int [] arr = { 1, 4, 2, 5, 3 };
List< int > ans = countOfSubArray(arr);
for ( int i = 0; i < ans.Count; i++) {
Console.Write(ans[i] + " " );
}
}
}
|
Javascript
<script>
const countOfSubArray = (arr) => {
let next, i, j;
let n = arr.length;
let ans = [];
for (i = 0; i < n; i++) {
let flag = false ;
next = n - i;
for (j = i + 1; j < n; j++) {
if (arr[i] > arr[j]) {
next = j - i;
ans.push(next);
flag = true ;
break ;
}
}
if (flag == false ) {
ans.push(next);
}
}
return ans;
}
let arr = [1, 4, 2, 5, 3];
let ans = countOfSubArray(arr);
for (let i = 0; i < ans.length; i++) {
document.write(`${ans[i]} `);
}
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Solution: This problem basically asks to find how far is the current index from the index of the next smaller number to the number at the current index. The most optimal way to solve this problem is by making use of a stack.
Follow the below steps to solve the problem:
- Iterate over each number of the given array arr[] using the current index.
- If the stack is empty, push the current index to the stack.
- If the stack is not empty then do the following:
- If the number at the current index is lesser than the number of the index at top of the stack, push the current index.
- If the number at the current index is greater than the number of the index at top of the stack, then update the count of subarrays as the index at top of the stack – current index
- Pop the stack once the number of days has been updated in the output list.
- Repeat the above steps for all the indices in the stack that are greater than the number at the current index.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > countOfSubArray(vector< int > arr)
{
stack< int > st;
vector< int > v;
int n = arr.size();
for ( int i = n - 1; i >= 0; i--) {
while (st.size() > 0
&& arr[st.top()] >= arr[i]) {
st.pop();
}
if (st.size() == 0) {
v.push_back(n - i);
}
else {
v.push_back(st.top() - i);
}
st.push(i);
}
reverse(v.begin(), v.end());
return v;
}
int main()
{
vector< int > arr{ 1, 4, 2, 5, 3 };
vector< int > ans = countOfSubArray(arr);
for ( int i = 0; i < ans.size(); i++) {
cout << ans[i] << " " ;
}
return 0;
}
|
Java
import java.util.*;
class GFG{
static Vector<Integer> countOfSubArray( int [] arr)
{
Stack<Integer> st = new Stack<Integer>();
Vector<Integer> v = new Vector<Integer>();
int n = arr.length;
for ( int i = n - 1 ; i >= 0 ; i--) {
while (st.size() > 0
&& arr[st.peek()] >= arr[i])
{
st.pop();
}
if (st.size() == 0 ) {
v.add(n - i);
}
else {
v.add(st.peek() - i);
}
st.add(i);
}
Collections.reverse(v);
return v;
}
public static void main(String[] args)
{
int []arr ={ 1 , 4 , 2 , 5 , 3 };
Vector<Integer> ans = countOfSubArray(arr);
for ( int i = 0 ; i < ans.size(); i++) {
System.out.print(ans.get(i)+ " " );
}
}
}
|
Python3
def countOfSubArray(arr):
st = []
v = []
n = len (arr)
for i in range (n - 1 , - 1 , - 1 ):
while len (st) > 0 and arr[st[ len (st) - 1 ]] > = arr[i] :
st.pop()
if ( len (st) = = 0 ):
v.append(n - i)
else :
v.append(st[ len (st) - 1 ] - i)
st.append(i)
v = v[:: - 1 ]
return v
arr = [ 1 , 4 , 2 , 5 , 3 ]
ans = countOfSubArray(arr)
for i in range ( len (ans)):
print (ans[i],end = " " )
|
C#
using System;
using System.Collections.Generic;
public class GFG{
static List< int > countOfSubArray( int [] arr)
{
Stack< int > st = new Stack< int >();
List< int > v = new List< int >();
int n = arr.Length;
for ( int i = n - 1; i >= 0; i--) {
while (st.Count > 0
&& arr[st.Peek()] >= arr[i])
{
st.Pop();
}
if (st.Count == 0) {
v.Add(n - i);
}
else {
v.Add(st.Peek() - i);
}
st.Push(i);
}
v.Reverse();
return v;
}
public static void Main(String[] args)
{
int []arr ={ 1, 4, 2, 5, 3 };
List< int > ans = countOfSubArray(arr);
for ( int i = 0; i < ans.Count; i++) {
Console.Write(ans[i]+ " " );
}
}
}
|
Javascript
<script>
function countOfSubArray(arr)
{
let st = [];
let v = [];
let n = arr.length;
for (let i = n - 1; i >= 0; i--) {
while (st.length > 0
&& arr[st[st.length-1]] >= arr[i])
{
st.pop();
}
if (st.length == 0) {
v.push(n - i);
}
else {
v.push(st[st.length - 1]- i);
}
st.push(i);
}
v.reverse();
return v;
}
let arr = [ 1, 4, 2, 5, 3 ];
let ans = countOfSubArray(arr);
for (let i = 0; i < ans.length; i++) {
document.write(ans[i], " " );
}
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...