📌  相关文章
📜  以索引 i 开始或结束的子数组的计数,使得 arr[i] 在子数组中是最大值

📅  最后修改于: 2021-10-26 06:42:13             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[] ,任务是找到从索引i开始或结束的子数组的数量,使得arr[i]是子数组的最大元素。

例子:

朴素方法:解决给定问题的最简单方法是对每个i索引,向后和向前迭代,直到子数组的最大值仍然等于arr[i] ,然后打印获得的子数组的总数。

时间复杂度: O(N 2 )
辅助空间: O(1)

有效的方法:可以通过为每个索引i存储下一个更大元素和前一个更大元素的索引并相应地为每个索引找到子数组的计数来优化上述方法。请按照以下步骤解决给定的问题:

  • 初始化两个数组pge[]nge[]以存储每个索引i的前一个更大元素和下一个更大元素的索引。
  • 为每个索引查找前一个大元素的索引,并将结果数组存储在pge[] 中
  • 为每个索引查找下一个更大元素的索引,并将结果数组存储在nge[] 中
  • 迭代范围[0, N – 1]并使用变量i并在每次迭代中打印从索引i开始或结束的子数组的计数,其中arr[i]作为最大值为nge[i] + pge[i ] – 1并打印此计数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find previous greater
// element
int* getPGE(int arr[], int n)
{
     
    // Stores the previous greater
    // element for each index
    int* pge = new int[n];
    stack stack;
 
    // Traverse the array
    for(int i = 0; i < n; i++)
    {
         
        // Iterate until stack is empty
        // and top element is less than
        // the current element arr[i]
        while (!stack.empty() &&
            arr[stack.top()] <= arr[i])
        {
            stack.pop();
        }
 
        // Update the previous greater
        // element for arr[i]
        pge[i] = stack.empty() ? -1 : stack.top();
 
        // Push the current index to
        // the stack
        stack.push(i);
    }
 
    // Return the PGE[] array
    return pge;
}
 
// Function to find the Next Greater Element
int* getNGE(int arr[], int n)
{
     
    // Stores the next greater element
    // for each index
    int* nge = new int[n];
    stack stack;
 
    // Traverse the array from the back
    for(int i = n - 1; i >= 0; i--)
    {
         
        // Iterate until stack is empty
        // and top element is less than
        // the current element arr[i]
        while (!stack.empty() &&
            arr[stack.top()] <= arr[i])
        {
            stack.pop();
        }
 
        // Update the next greater
        // element for arr[i]
        nge[i] = stack.empty() ? n : stack.top();
 
        // Push the current index
        stack.push(i);
    }
 
    // Return the NGE[] array
    return nge;
}
 
// Function to find the count of
// subarrays starting or ending at
// index i having arr[i] as maximum
void countSubarrays(int arr[], int n)
{
     
    // Function call to find the
    // previous greater element
    // for each array elements
    int* pge = getPGE(arr, n);
 
    // Function call to find the
    // previous greater element
    // for each elements
    int* nge = getNGE(arr, n);
 
    // Traverse the array arr[]
    for(int i = 0; i < n; i++)
    {
         
        // Print count of subarrays
        // satisfying the conditions
        cout << nge[i] - pge[i] - 1 << " ";
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 3, 4, 1, 6, 2 };
     
    int n = sizeof(arr) / sizeof(arr[0]);
     
    countSubarrays(arr, n);
     
    return 0;
}
 
// This code is contributed by Potta Lokesh


Java
// Java program for the above approach
import java.util.*;
 
public class GFG {
 
    // Function to find previous greater
    // element
    private static int[] getPGE(int[] arr)
    {
        // Stores the previous greater
        // element for each index
        int[] pge = new int[arr.length];
        Stack stack = new Stack<>();
 
        // Traverse the array
        for (int i = 0; i < arr.length; i++) {
 
            // Iterate until stack is empty
            // and top element is less than
            // the current element arr[i]
            while (!stack.isEmpty()
                   && arr[stack.peek()] <= arr[i]) {
                stack.pop();
            }
 
            // Update the previous greater
            // element for arr[i]
            pge[i] = stack.isEmpty() ? -1 : stack.peek();
 
            // Push the current index to
            // the stacl
            stack.push(i);
        }
 
        // Return the PGE[] array
        return pge;
    }
 
    // Function to find the Next Greater Element
    private static int[] getNGE(int[] arr)
    {
        // Stores the next greater element
        // for each index
        int[] nge = new int[arr.length];
        Stack stack = new Stack<>();
 
        // Traverse the array from the back
        for (int i = arr.length - 1; i >= 0; i--) {
 
            // Iterate until stack is empty
            // and top element is less than
            // the current element arr[i]
            while (!stack.isEmpty()
                   && arr[stack.peek()] <= arr[i]) {
                stack.pop();
            }
 
            // Update the next greater
            // element for arr[i]
            nge[i] = stack.isEmpty() ? arr.length
                                     : stack.peek();
 
            // Push the current index
            stack.push(i);
        }
 
        // Return the NGE[] array
        return nge;
    }
 
    // Function to find the count of
    // subarrays starting or ending at
    // index i having arr[i] as maximum
    private static void countSubarrays(int[] arr)
    {
 
        // Function call to find the
        // previous greater element
        // for each array elements
        int[] pge = getPGE(arr);
 
        // Function call to find the
        // previous greater element
        // for each elements
        int[] nge = getNGE(arr);
 
        // Traverse the array arr[]
        for (int i = 0; i < arr.length; i++) {
 
            // Print count of subarrays
            // satisfying the conditions
            System.out.print(
                nge[i] - pge[i] - 1 + " ");
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = new int[] { 3, 4, 1, 6, 2 };
        countSubarrays(arr);
    }
}


Python3
# Python program for the above approach
# Stores the previous greater
# element for each index
pge = []
 
# Stores the next greater element
# for each index
nge = []
 
# Function to find previous greater
# element
def getPGE(arr, n) :
  s = list()
   
  # Traverse the array
  for i in range(0, n):
     
    # Iterate until stack is empty
    # and top element is less than
    # the current element arr[i]
    while (len(s) > 0 and arr[s[-1]] <= arr[i]):
      s.pop()
       
    # Update the previous greater
    # element for arr[i]
    if len(s) == 0:
      pge.append(-1)
    else:
      pge.append(s[-1])
       
    # Push the current index
    s.append(i)
     
# Function to find the Next Greater Element  
def getNGE(arr, n) :
  s = list()
   
  # Traverse the array from the back
  for i in range(n-1, -1, -1):
     
    # Iterate until stack is empty
    # and top element is less than
    # the current element arr[i]
    while (len(s) > 0 and arr[s[-1]] <= arr[i]):
      s.pop()
       
    # Update the next greater
    # element for arr[i]
    if len(s) == 0:
      nge.append(n)
    else:
      nge.append(s[-1])
       
    # Push the current index
    s.append(i)
  nge.reverse();
   
# Function to find the count of
# subarrays starting or ending at
# index i having arr[i] as maximum
def countSubarrays(arr, n):
   
  # Function call to find the
  # previous greater element
  # for each array elements
  getNGE(arr, n);
   
  # Function call to find the
  # previous greater element
  # for each elements
  getPGE(arr, n);
   
  # Traverse the array arr[]
  for i in range(0,n):
    print(nge[i]-pge[i]-1,end = " ")
 
arr = [ 3, 4, 1, 6, 2 ]
n = len(arr)
countSubarrays(arr,n);
 
# This code is contributed by codersaty


C#
// C# program for the above approach
using System;
using System.Collections;
class GFG {
     
    // Function to find previous greater
    // element
    static int[] getPGE(int[] arr)
    {
       
        // Stores the previous greater
        // element for each index
        int[] pge = new int[arr.Length];
        Stack stack = new Stack();
  
        // Traverse the array
        for (int i = 0; i < arr.Length; i++) {
  
            // Iterate until stack is empty
            // and top element is less than
            // the current element arr[i]
            while (stack.Count > 0 && arr[(int)stack.Peek()] <= arr[i]) {
                stack.Pop();
            }
  
            // Update the previous greater
            // element for arr[i]
            pge[i] = stack.Count == 0 ? -1 : (int)stack.Peek();
  
            // Push the current index to
            // the stacl
            stack.Push(i);
        }
  
        // Return the PGE[] array
        return pge;
    }
  
    // Function to find the Next Greater Element
    static int[] getNGE(int[] arr)
    {
        // Stores the next greater element
        // for each index
        int[] nge = new int[arr.Length];
        Stack stack = new Stack();
  
        // Traverse the array from the back
        for (int i = arr.Length - 1; i >= 0; i--) {
  
            // Iterate until stack is empty
            // and top element is less than
            // the current element arr[i]
            while (stack.Count > 0 && arr[(int)stack.Peek()] <= arr[i]) {
                stack.Pop();
            }
  
            // Update the next greater
            // element for arr[i]
            nge[i] = stack.Count == 0 ? arr.Length : (int)stack.Peek();
  
            // Push the current index
            stack.Push(i);
        }
  
        // Return the NGE[] array
        return nge;
    }
  
    // Function to find the count of
    // subarrays starting or ending at
    // index i having arr[i] as maximum
    static void countSubarrays(int[] arr)
    {
  
        // Function call to find the
        // previous greater element
        // for each array elements
        int[] pge = getPGE(arr);
  
        // Function call to find the
        // previous greater element
        // for each elements
        int[] nge = getNGE(arr);
  
        // Traverse the array arr[]
        for (int i = 0; i < arr.Length; i++) {
  
            // Print count of subarrays
            // satisfying the conditions
            Console.Write((nge[i] - pge[i] - 1) + " ");
        }
    }
     
  // Driver code
  static void Main() {
    int[] arr = { 3, 4, 1, 6, 2 };
    countSubarrays(arr);
  }
}
 
// This code is contributed by divyesh072019.


Javascript


输出:
1 3 1 5 1

时间复杂度: O(N)
辅助空间: O(N)