📜  计算第二高在最高之前的子数组

📅  最后修改于: 2022-05-13 01:57:09.253000             🧑  作者: Mango

计算第二高在最高之前的子数组

给定一个包含至少大小为 2 的N个不同元素的数组。数组中的一对 (a, b) 定义为“a”是第二高元素的索引,“b”是数组中最高元素的索引。任务是计算所有子数组中 a < b 的所有不同对。

例子 :

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

解释 :
子数组 { 1 }, { 3 }, { 2 }, { 4 } 不包含任何这样的对
子数组 { 1, 3 }, { 2, 4 } 包含 (1, 2) 作为对
子数组 { 3, 2 } 不包含任何这样的对
子数组 { 3, 2, 4 } 包含 (1, 3) 作为一对
子数组 { 1, 3, 2 } 不包含任何这样的对
子数组 { 1, 3, 2, 4 } 包含 (2, 4) 作为一对
因此,有 3 个不同的对,它们是 (1, 2)、(1, 3) 和 (2, 4)。

方法1:(蛮力)——简单的方法可以,
1. 找到所有子数组。
2. 对于每个子数组,找到第二大和最大的元素。
3. 检查第二大元素是否位于最大元素之前。
4. 如果是,请检查该索引对是否已被计算在内。如果不存储该对并将计数加 1,否则忽略。
时间复杂度: O(n 2 )。

方法2:(使用堆栈)-
对于给定的数组 A,假设索引为curr (A[curr]) 处的元素,第一个大于它的元素,在它之后是 A[next],第一个元素大于它,在它之前是 A[prev]。观察到所有从 [prev + 1, curr] 范围内的任何索引开始到索引 next 结束的所有子数组,A[curr] 是第二大的,A[next] 是最大的,它们生成 (curr – prev + 1)最大和第二个最大值的差异为 (next – curr + 1)。

如果我们在数组中获得下一个和上一个更大的元素,并跟踪任何差异(最大和第二大)可能的最大对数。我们将需要添加所有这些数字。

现在剩下的唯一工作就是获得更大的元素(之后和之前)任何元素。为此,请参阅下一个更大的元素。
从数组中的起始元素开始遍历,以降序跟踪堆栈中的所有数字。到达任意数字后,从堆栈中弹出所有小于当前元素的元素,以获取大于它的数字的位置并将当前元素压入其上。这将为数组中的所有数字生成所需的值。

C++
// C++ program to count number of distinct instance
// where second highest number lie
// before highest number in all subarrays.
#include 
#define MAXN 100005
using namespace std;
 
// Finding the next greater element of the array.
void makeNext(int arr[], int n, int nextBig[])
{
    stack > 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(arr[i], i));
    }
}
 
// Finding the previous greater element of the array.
void makePrev(int arr[], int n, int prevBig[])
{
    stack > 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(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 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 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 s = new Stack();
 
    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 s = new Stack();
    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


输出 :

3

时间复杂度: O(n)