📜  Array 中每个索引的最长子数组的长度,其中该索引处的元素最大

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

Array 中每个索引的最长子数组的长度,其中该索引处的元素最大

给定一个大小为N的数组arr[] ,对于 i(0<=iarr[i] 的子数组的最大长度,其中arr[i]是最大元素。

例子:

天真的方法:

  1. 对于每个索引'i' ,遍历数组的两侧,直到找到大于arr[i]的元素。
  2. 计算范围内的元素数,这将是arr[i]是最大元素的子数组的最大长度。

时间复杂度: O(N 2 ),

高效方法:想法是使用堆栈数据结构来计算每个索引的下一个更大的元素(一次在左侧,一次在右侧)。

例如,

请按照以下步骤解决问题:

  1. 查找每个索引的下一个更大元素的索引,并使用每个i(0<=i
  2. 同样,为数组左侧的每个索引存储下一个更大的元素。
  3. 遍历数组并为每个索引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)