给定一个由N 个整数组成的数组arr[] ,任务是找到从索引i开始或结束的子数组的数量,使得arr[i]是子数组的最大元素。
例子:
Input: arr[] = {3, 4, 1, 6, 2}
Output: 1 3 1 5 1
Explanation:
- The subarray starting or ending at index 0 and with maximum arr[0](=3) is {3}. Therefore, the count is 1.
- The subarrays starting or ending at index 1 and with maximum arr[1](=4) are {3, 4}, {4}, and {4, 1}. Therefore, the count is 3.
- The subarray starting or ending at index 2 and with maximum arr[2](=1) is {1}. Therefore, the count is 1.
- The subarrays starting or ending at index 3 and with maximum arr[3](=6) are {3, 4, 1, 6}, {4, 1, 6}, {1, 6}, {6}, and {6, 2}. Therefore, the count is 5.
- The subarray starting or ending at index 4 and with maximum arr[4](=2) is {2}. Therefore, the count is 1.
Input: arr[] = {1, 2, 3}
Output: 1 2 3
朴素方法:解决给定问题的最简单方法是对每个第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)