Open In App

Count subarrays where second highest lie before highest

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of N distinct element of at least size 2. A pair (a, b) in an array is defined as ‘a’ is the index of second highest element and ‘b’ is the index of highest element in the array. The task is to count all the distinct pair where a < b in all the subarrays.

Examples :  

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

Explanation : 

The subarray { 1 }, { 3 }, { 2 }, { 4 } does not contain any such pair 
The subarray { 1, 3 }, { 2, 4 } contain (1, 2) as pair 
The subarray { 3, 2 } does not contain any such pair 
The subarray { 3, 2, 4 } contain (1, 3) as a pair 
The subarray { 1, 3, 2 } does not contain any such pair 
The subarray { 1, 3, 2, 4 } contain (2, 4) as a pair 
So, there are 3 distinct pairs, which are (1, 2), (1, 3) and (2, 4).

Method 1: (Brute Force): Simple approach can be, 

  1. Find all the subarrays. 
  2. For each subarray, find second largest and largest element. 
  3. Check if second largest element lie before largest element. 
  4. If so, check if such index pair is already counted or not. If not store the pair and increment the count by 1, else ignore. 

Time Complexity: O(n2).

Method 2: (Using stack):

For given array A, suppose for an element at index curr (A[curr]), first element greater than it and after it is A[next] and first element greater than it and before it A[prev]. Observe that for all subarray starting from any index in range [prev + 1, curr] and ending at index next, A[curr] is the second largest and A[next] is the largest, which generate (curr – prev + 1) pairs in total with difference of (next – curr + 1) in maximum and second maximum.

If we get next and prev greater element in an array, and keep track of maximum number of pairs possible for any difference (of largest and second largest). We will need to add all these numbers.

Now only job left is to get greater element (after and before) any element. For this, refer Next Greater Element.
Traverse from the starting element in an array, keeping track of all numbers in the stack in decreasing order. After arriving at any number, pop all elements from stack which are less than current element to get location of number bigger than it and push current element on it. This generates required value for all numbers in the array. 

Implementation:

C++




// C++ program to count number of distinct instance
// where second highest number lie
// before highest number in all subarrays.
#include <bits/stdc++.h>
#define MAXN 100005
using namespace std;
 
// Finding the next greater element of the array.
void makeNext(int arr[], int n, int nextBig[])
{
    stack<pair<int, int> > s;
 
    for (int i = n - 1; i >= 0; i--) {
 
        nextBig[i] = i;
        while (!s.empty() && s.top().first < arr[i])
            s.pop();
 
        if (!s.empty())
            nextBig[i] = s.top().second;
 
        s.push(pair<int, int>(arr[i], i));
    }
}
 
// Finding the previous greater element of the array.
void makePrev(int arr[], int n, int prevBig[])
{
    stack<pair<int, int> > s;
    for (int i = 0; i < n; i++) {
 
        prevBig[i] = -1;
        while (!s.empty() && s.top().first < arr[i])
            s.pop();
 
        if (!s.empty())
            prevBig[i] = s.top().second;
 
        s.push(pair<int, int>(arr[i], i));
    }
}
 
// Wrapper Function
int wrapper(int arr[], int n)
{
    int nextBig[MAXN];
    int prevBig[MAXN];
    int maxi[MAXN];
    int ans = 0;
 
    // Finding previous largest element
    makePrev(arr, n, prevBig);
 
    // Finding next largest element
    makeNext(arr, n, nextBig);
 
    for (int i = 0; i < n; i++)
        if (nextBig[i] != i)
            maxi[nextBig[i] - i] = max(maxi[nextBig[i] - i],
                                       i - prevBig[i]);
 
    for (int i = 0; i < n; i++)
        ans += maxi[i];
 
    return ans;
}
 
// Driven Program
int main()
{
    int arr[] = { 1, 3, 2, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << wrapper(arr, n) << endl;
    return 0;
}


Java




// Java program to count number of distinct instance
// where second highest number lie
// before highest number in all subarrays.
import java.util.*;
 
class GFG
{
     
static int MAXN = 100005;
 
static class pair
{
    int first, second;
    public pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
}
// Finding the next greater element of the array.
static void makeNext(int arr[], int n, int nextBig[])
{
    Stack<pair> s = new Stack<>();
 
    for (int i = n - 1; i >= 0; i--)
    {
 
        nextBig[i] = i;
        while (!s.empty() && s.peek().first < arr[i])
            s.pop();
 
        if (!s.empty())
            nextBig[i] = s.peek().second;
 
        s.push(new pair(arr[i], i));
    }
}
 
// Finding the previous greater element of the array.
static void makePrev(int arr[], int n, int prevBig[])
{
    Stack<pair> s = new Stack<>();
    for (int i = 0; i < n; i++)
    {
 
        prevBig[i] = -1;
        while (!s.empty() && s.peek().first < arr[i])
            s.pop();
 
        if (!s.empty())
            prevBig[i] = s.peek().second;
 
        s.push(new pair(arr[i], i));
    }
}
 
// Wrapper Function
static int wrapper(int arr[], int n)
{
    int []nextBig = new int[MAXN];
    int []prevBig = new int[MAXN];
    int []maxi = new int[MAXN];
    int ans = 0;
 
    // Finding previous largest element
    makePrev(arr, n, prevBig);
 
    // Finding next largest element
    makeNext(arr, n, nextBig);
 
    for (int i = 0; i < n; i++)
        if (nextBig[i] != i)
            maxi[nextBig[i] - i] = Math.max(maxi[nextBig[i] - i],
                                    i - prevBig[i]);
 
    for (int i = 0; i < n; i++)
        ans += maxi[i];
 
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
 
    int arr[] = { 1, 3, 2, 4 };
    int n = arr.length;
 
    System.out.println(wrapper(arr, n));
    }
}
 
// This code is contributed by Princi Singh


Python3




# Python3 program to count number of distinct
# instance where second highest number lie
# before highest number in all subarrays.
from typing import List
 
MAXN = 100005
 
# Finding the next greater element
# of the array.
def makeNext(arr: List[int], n: int,
         nextBig: List[int]) -> None:
 
    # Stack
    s = []
 
    for i in range(n - 1, -1, -1):
        nextBig[i] = i
         
        while len(s) and s[-1][0] < arr[i]:
            s.pop()
 
        if len(s):
            nextBig[i] = s[-1][1]
 
        s.append((arr[i], i))
 
# Finding the previous greater
# element of the array.
def makePrev(arr: List[int], n: int,
         prevBig: List[int]) -> None:
 
    # Stack
    s = []
    for i in range(n):
        prevBig[i] = -1
         
        while (len(s) and s[-1][0] < arr[i]):
            s.pop()
 
        if (len(s)):
            prevBig[i] = s[-1][1]
 
        s.append((arr[i], i))
 
# Wrapper Function
def wrapper(arr: List[int], n: int) -> int:
 
    nextBig = [0] * MAXN
    prevBig = [0] * MAXN
    maxi = [0] * MAXN
    ans = 0
 
    # Finding previous largest element
    makePrev(arr, n, prevBig)
 
    # Finding next largest element
    makeNext(arr, n, nextBig)
 
    for i in range(n):
        if (nextBig[i] != i):
            maxi[nextBig[i] - i] = max(
                maxi[nextBig[i] - i],
                    i - prevBig[i])
 
    for i in range(n):
        ans += maxi[i]
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    arr = [ 1, 3, 2, 4 ]
    n = len(arr)
     
    print(wrapper(arr, n))
 
# This code is contributed by sanjeev2552


C#




// C# program to count number of distinct instance
// where second highest number lie
// before highest number in all subarrays.
using System;
using System.Collections.Generic;
     
class GFG
{
     
static int MAXN = 100005;
public class pair
{
    public int first, second;
    public pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
}
 
// Finding the next greater element of the array.
static void makeNext(int []arr, int n, int []nextBig)
{
    Stack<pair> s = new Stack<pair>();
 
    for (int i = n - 1; i >= 0; i--)
    {
 
        nextBig[i] = i;
        while (s.Count!=0 && s.Peek().first < arr[i])
            s.Pop();
 
        if (s.Count!=0)
            nextBig[i] = s.Peek().second;
 
        s.Push(new pair(arr[i], i));
    }
}
 
// Finding the previous greater element of the array.
static void makePrev(int []arr, int n, int[] prevBig)
{
    Stack<pair> s = new Stack<pair>();
    for (int i = 0; i < n; i++)
    {
 
        prevBig[i] = -1;
        while (s.Count!=0 && s.Peek().first < arr[i])
            s.Pop();
 
        if (s.Count!=0)
            prevBig[i] = s.Peek().second;
 
        s.Push(new pair(arr[i], i));
    }
}
 
// Wrapper Function
static int wrapper(int []arr, int n)
{
    int []nextBig = new int[MAXN];
    int []prevBig = new int[MAXN];
    int []maxi = new int[MAXN];
    int ans = 0;
 
    // Finding previous largest element
    makePrev(arr, n, prevBig);
 
    // Finding next largest element
    makeNext(arr, n, nextBig);
 
    for (int i = 0; i < n; i++)
        if (nextBig[i] != i)
            maxi[nextBig[i] - i] = Math.Max(maxi[nextBig[i] - i],
                                    i - prevBig[i]);
 
    for (int i = 0; i < n; i++)
        ans += maxi[i];
 
    return ans;
}
 
// Driver code
public static void Main(String[] args)
{
 
    int[] arr = { 1, 3, 2, 4 };
    int n = arr.Length;
 
    Console.WriteLine(wrapper(arr, n));
}
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
 
// JavaScript program to count number of distinct instance
// where second highest number lie
// before highest number in all subarrays.
var MAXN = 100005;
 
// Finding the next greater element of the array.
function makeNext(arr, n, nextBig)
{
    var s = [];
 
    for (var i = n - 1; i >= 0; i--) {
 
        nextBig[i] = i;
        while (s.length!=0 && s[s.length-1][0] < arr[i])
            s.pop();
 
        if (s.length!=0)
            nextBig[i] = s[s.length-1][1];
 
        s.push([arr[i], i]);
    }
}
 
// Finding the previous greater element of the array.
function makePrev(arr, n, prevBig)
{
    var s = [];
    for (var i = 0; i < n; i++) {
 
        prevBig[i] = -1;
        while (s.length!=0 && s[s.length-1][0] < arr[i])
            s.pop();
 
        if (s.length!=0)
            prevBig[i] = s[s.length-1][1];
 
        s.push([arr[i], i]);
    }
}
 
// Wrapper Function
function wrapper( arr, n)
{
    var nextBig = Array(MAXN).fill(0);
    var prevBig= Array(MAXN).fill(0);
    var maxi= Array(MAXN).fill(0);
    var ans = 0;
 
    // Finding previous largest element
    makePrev(arr, n, prevBig);
 
    // Finding next largest element
    makeNext(arr, n, nextBig);
 
    for (var i = 0; i < n; i++)
        if (nextBig[i] != i)
            maxi[nextBig[i] - i] = Math.max(maxi[nextBig[i] - i],
                                       i - prevBig[i]);
 
    for (var i = 0; i < n; i++)
        ans += maxi[i];
 
    return ans;
}
 
// Driven Program
 
var arr = [1, 3, 2, 4];
var n = arr.length;
document.write( wrapper(arr, n));
 
 
</script>


Output

3

Complexity Analysis:

  • Time Complexity: O(n)
  • Space Complexity: O(n) in the worst case.

 



Last Updated : 27 Jul, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads