Array 中每个索引的最长子数组的长度,其中该索引处的元素最大
给定一个大小为N的数组arr[] ,对于 i(0<=i
例子:
Input : arr[ ] = {62, 97, 49, 59, 54, 92, 21}, N=7
Output:
1 7 1 3 1 5 1
Explanation: The maximum length of subarray in which 1st index element is maximum is 1, the subarray consisting of only first element.
For second element, i.e. 97, maximum length of subarray = 7. We can observe that 97 is the maximum element in the array A.
For third element, only 49 can be in the subarray. Hence, maximum length that is possible = 1.
For fourth element, subarray [49, 59, 54] is possible where 59 is the maximum number. Hence, length = 3.
Likewise, we calculate for each index in the array.
Input: arr[]={1, 4, 5, 2, 3}
Output:
1 2 5 1 2
天真的方法:
- 对于每个索引'i' ,遍历数组的两侧,直到找到大于arr[i]的元素。
- 计算范围内的元素数,这将是arr[i]是最大元素的子数组的最大长度。
时间复杂度: O(N 2 ),
高效方法:想法是使用堆栈数据结构来计算每个索引的下一个更大的元素(一次在左侧,一次在右侧)。
例如,
Let arr[]={1, 3, 1, 2, 1, 5}, for i=3, the next greater element on the left is at index 1
and on the right is at index 5.
Thus, the length of the subarray in which it is the largest is 5-1-1=3 i.e from indices 2 to 4 or {1, 2, 1}
请按照以下步骤解决问题:
- 查找每个索引的下一个更大元素的索引,并使用每个i(0<=i
- 同样,为数组左侧的每个索引存储下一个更大的元素。
- 遍历数组并为每个索引i打印左侧下一个较大元素与右侧下一个较大元素之间的元素数。
C++
// C++ code for the above approach
#include
using namespace std;
// Function to compute
// next greater element indices on the
// right side on any index
vector rightGreaterElement(int arr[], int n)
{
// to store the elements of array arr
// with their index
vector > B(n);
for (int i = 0; i < n; i++) {
B[i].first = arr[i];
B[i].second = i;
}
// to store indices of next greater element
// on the right side
vector vec(n, -1);
// to store the pairs
stack > st;
for (int i = 0; i < n; i++) {
// if the stack is empty,
// push the pair
if (st.empty()) {
st.push(B[i]);
}
else {
// Pop and assign till
// the top is smaller
while (!st.empty()
&& st.top().first < B[i].first) {
vec[st.top().second] = B[i].second;
st.pop();
}
st.push(B[i]);
}
}
// assign n to element
// having no next greater element
while (!st.empty()) {
vec[st.top().second] = n;
st.pop();
}
// return the vector
return vec;
}
// Function to compute next greater element
// indices on the left side on any index
vector leftGreaterElement(int arr[], int n)
{
// store the elements of array arr
// with their index
vector > B(n);
for (int i = 0; i < n; i++) {
B[i].first = arr[i];
B[i].second = i;
}
// array to store indices of next
// greater element on the left side
vector vec(n, -1);
// stack to store the pairs
stack > st;
for (int i = n - 1; i >= 0; i--) {
// if the stack is empty, push the pair
if (st.empty()) {
st.push(B[i]);
}
else {
// pop and assign till top is smaller
while (!st.empty()
&& st.top().first < B[i].first) {
vec[st.top().second] = B[i].second;
st.pop();
}
st.push(B[i]);
}
}
// assign -1 to element having
// no next greater element
while (!st.empty()) {
vec[st.top().second] = -1;
st.pop();
}
// returning the vector
// with indices of next greater
// elements on the left side.
return vec;
}
// Function to print the maximum
// length of subarrays for all
// indices where A[i] is the
// maximum element in the subarray
void maximumSubarrayLength(int arr[], int N)
{
// array having index of next
// greater element on the right side.
vector right = rightGreaterElement(arr, N);
// array having index of next
// greater element on the left side.
vector left = leftGreaterElement(arr, N);
// print the range between the
// next greater elements on both the sides.
for (int i = 0; i < N; i++) {
int l = left[i];
int r = right[i];
cout << r - l - 1 << " ";
}
}
// Driver code
int main()
{
// Input
int arr[] = { 62, 97, 49, 59, 54, 92, 21 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
maximumSubarrayLength(arr, N);
return 0;
}
Java
// Java code for the above approach
import java.util.*;
import java.awt.Point;
public class Main
{
// Function to compute
// next greater element indices on the
// right side on any index
static int[] rightGreaterElement(int[] arr, int n)
{
// to store the elements of array arr
// with their index
int[][] B = new int[n][2];
for (int i = 0; i < n; i++) {
B[i][0] = arr[i];
B[i][1] = i;
}
// to store indices of next greater element
// on the right side
int[] vec = new int[n];
Arrays.fill(vec, -1);
// to store the pairs
Stack st = new Stack();
for (int i = 0; i < n; i++) {
// if the stack is empty,
// push the pair
if (st.size() == 0) {
st.push(new Point(B[i][0], B[i][1]));
}
else {
// Pop and assign till
// the top is smaller
while (st.size() > 0 && (st.peek()).x < B[i][0]) {
vec[(st.peek()).y] = B[i][1];
st.pop();
}
st.push(new Point(B[i][0], B[i][1]));
}
}
// assign n to element
// having no next greater element
while (st.size() > 0) {
vec[(st.peek()).y] = n;
st.pop();
}
// return the vector
return vec;
}
// Function to compute next greater element
// indices on the left side on any index
static int[] leftGreaterElement(int[] arr, int n)
{
// store the elements of array arr
// with their index
int[][] B = new int[n][2];
for (int i = 0; i < n; i++) {
B[i][0] = arr[i];
B[i][1] = i;
}
// array to store indices of next
// greater element on the left side
int[] vec = new int[n];
Arrays.fill(vec, -1);
// stack to store the pairs
Stack st = new Stack();
for (int i = n - 1; i >= 0; i--) {
// if the stack is empty, push the pair
if (st.size() == 0) {
st.push(new Point(B[i][0], B[i][1]));
}
else {
// pop and assign till top is smaller
while (st.size() > 0 && (st.peek()).x < B[i][0]) {
vec[(st.peek()).y] = B[i][1];
st.pop();
}
st.push(new Point(B[i][0], B[i][1]));
}
}
// assign -1 to element having
// no next greater element
while (st.size() > 0) {
vec[(st.peek()).y] = -1;
st.pop();
}
// returning the vector
// with indices of next greater
// elements on the left side.
return vec;
}
// Function to print the maximum
// length of subarrays for all
// indices where A[i] is the
// maximum element in the subarray
static void maximumSubarrayLength(int[] arr, int N)
{
// array having index of next
// greater element on the right side.
int[] right = rightGreaterElement(arr, N);
// array having index of next
// greater element on the left side.
int[] left = leftGreaterElement(arr, N);
// print the range between the
// next greater elements on both the sides.
for (int i = 0; i < N; i++) {
int l = left[i];
int r = right[i];
System.out.print((r - l - 1) + " ");
}
}
public static void main(String[] args) {
// Input
int[] arr = { 62, 97, 49, 59, 54, 92, 21 };
int N = arr.length;
// Function call
maximumSubarrayLength(arr, N);
}
}
// This code is contributed by mukesh07.
Python3
# Python3 code for the above approach
# Function to compute next greater
# element indices on the right side
# on any index
def rightGreaterElement(arr, n):
# To store the elements of array arr
# with their index
B = [[0, 0] for i in range(n)]
for i in range(n):
B[i][0] = arr[i]
B[i][1] = i
# To store indices of next greater element
# on the right side
vec = [-1 for i in range(n)]
# To store the pairs
st = []
for i in range(n):
# If the stack is empty,
# push the pair
if (len(st) == 0):
st.append(B[i])
else:
# Pop and assign till
# the top is smaller
while (len(st) > 0 and st[-1][0] < B[i][0]):
vec[st[-1][1]] = B[i][1]
st.pop()
st.append(B[i])
# Assign n to element
# having no next greater element
while (len(st) > 0):
vec[st[-1][1]] = n
st.pop()
# Return the vector
return vec
# Function to compute next greater element
# indices on the left side on any index
def leftGreaterElement(arr, n):
# Store the elements of array arr
# with their index
B = [[0,0] for i in range(n)]
for i in range(n):
B[i][0] = arr[i]
B[i][1] = i
# Array to store indices of next
# greater element on the left side
vec = [-1 for i in range(n)]
# Stack to store the pairs
st = []
i = n - 1
while(i >= 0):
# If the stack is empty, push the pair
if (len(st) == 0):
st.append(B[i])
else:
# Pop and assign till top is smaller
while (len(st) > 0 and st[-1][0] < B[i][0]):
vec[st[-1][1]] = B[i][1]
st.pop()
st.append(B[i])
i -= 1
# Assign -1 to element having
# no next greater element
while (len(st) > 0):
vec[st[-1][1]] = -1
st.pop()
# Returning the vector
# with indices of next greater
# elements on the left side.
return vec
# Function to print the maximum
# length of subarrays for all
# indices where A[i] is the
# maximum element in the subarray
def maximumSubarrayLength(arr, N):
# Array having index of next
# greater element on the right side.
right = rightGreaterElement(arr, N)
# Array having index of next
# greater element on the left side.
left = leftGreaterElement(arr, N)
# Print the range between the
# next greater elements on both the sides.
for i in range(N):
l = left[i]
r = right[i]
print(r - l - 1, end = " ")
# Driver code
if __name__ == '__main__':
# Input
arr = [ 62, 97, 49, 59, 54, 92, 21 ]
N = len(arr)
# Function call
maximumSubarrayLength(arr, N)
# This code is contributed by ipg2016107
C#
// C# code for the above approach
using System;
using System.Collections;
class GFG {
// Function to compute
// next greater element indices on the
// right side on any index
static int[] rightGreaterElement(int[] arr, int n)
{
// to store the elements of array arr
// with their index
int[,] B = new int[n,2];
for (int i = 0; i < n; i++) {
B[i,0] = arr[i];
B[i,1] = i;
}
// to store indices of next greater element
// on the right side
int[] vec = new int[n];
Array.Fill(vec, -1);
// to store the pairs
Stack st = new Stack();
for (int i = 0; i < n; i++) {
// if the stack is empty,
// push the pair
if (st.Count == 0) {
st.Push(new Tuple(B[i,0], B[i,1]));
}
else {
// Pop and assign till
// the top is smaller
while (st.Count > 0
&& ((Tuple)st.Peek()).Item1 < B[i,0]) {
vec[((Tuple)st.Peek()).Item2] = B[i,1];
st.Pop();
}
st.Push(new Tuple(B[i,0], B[i,1]));
}
}
// assign n to element
// having no next greater element
while (st.Count > 0) {
vec[((Tuple)st.Peek()).Item2] = n;
st.Pop();
}
// return the vector
return vec;
}
// Function to compute next greater element
// indices on the left side on any index
static int[] leftGreaterElement(int[] arr, int n)
{
// store the elements of array arr
// with their index
int[,] B = new int[n,2];
for (int i = 0; i < n; i++) {
B[i,0] = arr[i];
B[i,1] = i;
}
// array to store indices of next
// greater element on the left side
int[] vec = new int[n];
Array.Fill(vec, -1);
// stack to store the pairs
Stack st = new Stack();
for (int i = n - 1; i >= 0; i--) {
// if the stack is empty, push the pair
if (st.Count == 0) {
st.Push(new Tuple(B[i,0], B[i,1]));
}
else {
// pop and assign till top is smaller
while (st.Count > 0
&& ((Tuple)st.Peek()).Item1 < B[i,0]) {
vec[((Tuple)st.Peek()).Item2] = B[i,1];
st.Pop();
}
st.Push(new Tuple(B[i,0], B[i,1]));
}
}
// assign -1 to element having
// no next greater element
while (st.Count > 0) {
vec[((Tuple)st.Peek()).Item2] = -1;
st.Pop();
}
// returning the vector
// with indices of next greater
// elements on the left side.
return vec;
}
// Function to print the maximum
// length of subarrays for all
// indices where A[i] is the
// maximum element in the subarray
static void maximumSubarrayLength(int[] arr, int N)
{
// array having index of next
// greater element on the right side.
int[] right = rightGreaterElement(arr, N);
// array having index of next
// greater element on the left side.
int[] left = leftGreaterElement(arr, N);
// print the range between the
// next greater elements on both the sides.
for (int i = 0; i < N; i++) {
int l = left[i];
int r = right[i];
Console.Write((r - l - 1) + " ");
}
}
static void Main()
{
// Input
int[] arr = { 62, 97, 49, 59, 54, 92, 21 };
int N = arr.Length;
// Function call
maximumSubarrayLength(arr, N);
}
}
// This code is contributed by divyesh072019.
Javascript
1 7 1 3 1 5 1
时间复杂度: O(N)
辅助空间: O(N)