📜  左右下一个较大的索引的最大乘积

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

左右下一个较大的索引的最大乘积

给定一个数组 a[1..N]。对于位置 i (1 <= i <= N) 处的每个元素。在哪里

  1. L(i)被定义为最接近的索引 j,使得 j < i 并且 a[j] > a[i]。如果不存在这样的 j 则L(i) = 0
  2. R(i)被定义为最接近的索引 k,使得 k > i 并且 a[k] > a[i]。如果不存在这样的 k 则R(i) = 0

LRProduct(i) = L(i)*R(i)
我们需要找到一个具有最大 LRProduct 的索引

例子:

注意:以起始索引为 1 查找 LRproduct。

这个问题基于 Next Greater Element。
从当前位置开始,我们需要在其左右两侧找到最近的较大元素。
所以为了找到下一个更大的元素,我们使用了从左到右的堆栈。简单地说,我们正在检查哪个元素更大并将它们的索引存储在指定的位置。
1-如果堆栈为空,则推送当前索引。
2-如果堆栈不为空
....a)如果当前元素大于顶部元素,则将当前元素的索引存储在顶部元素的索引上。
这样做,一次从左侧遍历数组元素,一次从右侧遍历数组元素并形成左右数组,然后将它们相乘以找到最大乘积值。

C++
// C++ program to find the max
// LRproduct[i] among all i
#include 
using namespace std;
#define MAX 1000
 
// function to find just next greater
// element in left side
vector nextGreaterInLeft(int a[], int n)
{
    vector left_index(MAX, 0);
    stack s;
 
    for (int i = n - 1; i >= 0; i--) {
 
        // checking if current element is greater than top
        while (!s.empty() && a[i] > a[s.top() - 1]) {
            int r = s.top();
            s.pop();
 
            // on index of top store the current element
            // index which is just greater than top element
            left_index[r - 1] = i + 1;
        }
 
        // else push the current element in stack
        s.push(i + 1);
    }
    return left_index;
}
 
// function to find just next greater element
// in right side
vector nextGreaterInRight(int a[], int n)
{
    vector right_index(MAX, 0);
    stack s;
    for (int i = 0; i < n; ++i) {
 
        // checking if current element is greater than top
        while (!s.empty() && a[i] > a[s.top() - 1]) {
            int r = s.top();
            s.pop();
 
            // on index of top store the current element
            // index which is just greater than top element
            // stored index should be start with 1
            right_index[r - 1] = i + 1;
        }
 
        // else push the current element in stack
        s.push(i + 1);
    }
    return right_index;
}
 
// Function to find maximum LR product
int LRProduct(int arr[], int n)
{
    // for each element storing the index of just
    // greater element in left side
    vector left = nextGreaterInLeft(arr, n);
 
    // for each element storing the index of just
    // greater element in right side
    vector right = nextGreaterInRight(arr, n);
    int ans = -1;
    for (int i = 1; i <= n; i++) {
 
        // finding the max index product
        ans = max(ans, left[i] * right[i]);
    }
 
    return ans;
}
 
// Drivers code
int main()
{
    int arr[] = { 5, 4, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[1]);
 
    cout << LRProduct(arr, n);
 
    return 0;
}


Java
// Java program to find the
// max LRproduct[i] among all i
import java.io.*;
import java.util.*;
 
class GFG
{
    static int MAX = 1000;
     
    // function to find just next
    // greater element in left side
    static int[] nextGreaterInLeft(int []a,
                                   int n)
    {
        int []left_index = new int[MAX];
        Stack s = new Stack();
     
        for (int i = n - 1; i >= 0; i--)
        {
     
            // checking if current
            // element is greater than top
            while (s.size() != 0 &&
                     a[i] > a[s.peek() - 1])
            {
                int r = s.peek();
                s.pop();
     
                // on index of top store
                // the current element
                // index which is just
                // greater than top element
                left_index[r - 1] = i + 1;
            }
     
            // else push the current
            // element in stack
            s.push(i + 1);
        }
        return left_index;
    }
     
    // function to find just next
    // greater element in right side
    static int[] nextGreaterInRight(int []a,
                                    int n)
    {
        int []right_index = new int[MAX];
        Stack s = new Stack();
        for (int i = 0; i < n; ++i) {
     
            // checking if current element
            // is greater than top
            while (s.size() != 0 &&
                        a[i] > a[s.peek() - 1])
            {
                int r = s.peek();
                s.pop();
     
                // on index of top store
                // the current element index
                // which is just greater than
                // top element stored index
                // should be start with 1
                right_index[r - 1] = i + 1;
            }
     
            // else push the current
            // element in stack
            s.push(i + 1);
        }
        return right_index;
    }
     
    // Function to find
    // maximum LR product
    static int LRProduct(int []arr, int n)
    {
         
        // for each element storing
        // the index of just greater
        // element in left side
        int []left = nextGreaterInLeft(arr, n);
     
        // for each element storing
        // the index of just greater
        // element in right side
        int []right = nextGreaterInRight(arr, n);
        int ans = -1;
        for (int i = 1; i <= n; i++)
        {
     
            // finding the max
            // index product
            ans = Math.max(ans, left[i] *
                                right[i]);
        }
     
        return ans;
    }
     
    // Driver code
    public static void main(String args[])
    {
        int []arr = new int[]{ 5, 4, 3, 4, 5 };
        int n = arr.length;
     
        System.out.print(LRProduct(arr, n));
    }
}
 
// This code is contributed by
// Manish Shaw(manishshaw1)


Python3
# Python3 program to find the 
# max LRproduct[i] among all i
 
# Method to find the next greater
# value in left side
def nextGreaterInLeft(a):
     
    left_index = [0] * len(a)
    s = []
     
    for i in range(len(a)):
         
        # Checking if current
        # element is greater than top
        while len(s) != 0 and a[i] >= a[s[-1]]:
             
            # Pop the element till we can't
            # get the larger value then
            # the current value
            s.pop()
             
        if len(s) != 0:
            left_index[i] = s[-1]
        else:
            left_index[i] = 0
 
        # Else push the element in the stack
        s.append(i)
 
    return left_index
         
# Method to find the next
# greater value in right
def nextGreaterInRight(a):
     
    right_index = [0] * len(a)
    s = []
     
    for i in range(len(a) - 1, -1, -1):
         
        # Checking if current element
        # is greater than top
        while len(s) != 0 and a[i] >= a[s[-1]]:
             
            # Pop the element till we can't
            # get the larger value then
            # the current value
            s.pop()
             
        if len(s) != 0:
            right_index[i] = s[-1]
        else:
            right_index[i] = 0
             
        # Else push the element in the stack
        s.append(i)
 
    return right_index
         
def LRProduct(arr):
     
    # For each element storing
    # the index of just greater
    # element in left side
    left = nextGreaterInLeft(arr)
 
    # For each element storing
    # the index of just greater
    # element in right side
    right = nextGreaterInRight(arr)
 
    ans = -1
 
    # As we know the answer will
    # belong to the range from
    # 1st index to second last index.
    # Because for 1st index left
    # will be 0 and for last
    # index right will be 0
    for i in range(1, len(left) - 1):
         
        if left[i] == 0 or right[i] == 0:
             
            # Finding the max index product
            ans = max(ans, 0)
        else:
            temp = (left[i] + 1) * (right[i] + 1)
             
            # Finding the max index product
            ans = max(ans, temp)
 
    return ans
 
# Driver Code
arr = [ 5, 4, 3, 4, 5 ]
 
print(LRProduct(arr))
 
# This code is contributed by Mohit Pathneja


C#
// C# program to find the max LRproduct[i]
// among all i
using System;
using System.Collections.Generic;
 
class GFG {
     
    static int MAX = 1000;
     
    // function to find just next greater
    // element in left side
    static int[] nextGreaterInLeft(int []a, int n)
    {
        int []left_index = new int[MAX];
        Stack s = new Stack();
     
        for (int i = n - 1; i >= 0; i--) {
     
            // checking if current element is
            // greater than top
            while (s.Count != 0 && a[i] > a[s.Peek() - 1])
            {
                int r = s.Peek();
                s.Pop();
     
                // on index of top store the current
                // element index which is just greater
                // than top element
                left_index[r - 1] = i + 1;
            }
     
            // else push the current element in stack
            s.Push(i + 1);
        }
        return left_index;
    }
     
    // function to find just next greater element
    // in right side
    static int[] nextGreaterInRight(int []a, int n)
    {
        int []right_index = new int[MAX];
        Stack s = new Stack();
        for (int i = 0; i < n; ++i) {
     
            // checking if current element is
            // greater than top
            while (s.Count != 0 && a[i] > a[s.Peek() - 1])
            {
                int r = s.Peek();
                s.Pop();
     
                // on index of top store the current
                // element index which is just greater
                // than top element stored index should
                // be start with 1
                right_index[r - 1] = i + 1;
            }
     
            // else push the current element in stack
            s.Push(i + 1);
        }
        return right_index;
    }
     
    // Function to find maximum LR product
    static int LRProduct(int []arr, int n)
    {
         
        // for each element storing the index of just
        // greater element in left side
        int []left = nextGreaterInLeft(arr, n);
     
        // for each element storing the index of just
        // greater element in right side
        int []right = nextGreaterInRight(arr, n);
        int ans = -1;
        for (int i = 1; i <= n; i++) {
     
            // finding the max index product
            ans = Math.Max(ans, left[i] * right[i]);
        }
     
        return ans;
    }
     
    // Drivers code
    static void Main()
    {
        int []arr = new int[]{ 5, 4, 3, 4, 5 };
        int n = arr.Length;
     
        Console.Write(LRProduct(arr, n));
    }
}
 
// This code is contributed by Manish Shaw


Javascript


C++
// C++ program to find max LR product
#include 
using namespace std;
 
stack mystack;
      
// To find greater element to left
void nextGreaterToLeft(int arr[], int res[], int N) {
    mystack.push(0);
    res[0] = 0;
      
    // iterate through the array
    for(int i = 1; i < N; i++) {
        while(mystack.size() > 0  &&  arr[mystack.top()] <= arr[i])
            mystack.pop();
          
        // place the index to the left in the resultant array
        res[i] = (mystack.size() == 0) ? 0 : mystack.top()+1;
        mystack.push(i);
    }
}
  
//// To find greater element to right
void nextGreaterToRight(int arr[], int res[], int N) {
    mystack = stack();
      
    int n = N;
    mystack.push(n-1);
    res[n-1] *= 0;
      
    // iterate through the array in the reverse order
    for(int i=n - 2 ; i >= 0; i--) {
        while(mystack.size() > 0  &&  arr[mystack.top()] <= arr[i])
            mystack.pop();
          
        //multiply the index to the right with the index to the left
        //in the resultant array
        res[i] = (mystack.size() == 0) ? res[i]*0 : res[i]*(mystack.top()+1);
        mystack.push(i);
    }
}
  
//function to return the max value in the resultant array
int maxProduct(int arr[], int res[], int N) {
    nextGreaterToLeft(arr,res, N);        //to find left max
    nextGreaterToRight(arr,res, N);    //to find right max
 
    int Max = res[0];
    for(int i = 1; i < N; i++){
        Max = max(Max, res[i]);
    }
    return Max;
}
     
int main()
{
    int arr[] = {5, 4, 3, 4, 5};
    int N = sizeof(arr) / sizeof(arr[0]);
    int res[N];
      
    int maxprod = maxProduct(arr, res, N);
    cout << maxprod << endl;
 
    return 0;
}
 
// This code is contributed by decode2207.


Java
//java program to find max LR product
 
import java.util.*;
 
public class GFG {
    Stack mystack = new Stack<>();
     
    //To find greater element to left
    void nextGreaterToLeft(int[] arr,int[] res) {
        mystack.push(0);
        res[0] = 0;
         
        //iterate through the array
        for(int i=1;i=0;i--) {
            while(!mystack.isEmpty()  &&  arr[mystack.peek()] <= arr[i])
                mystack.pop();
             
            //multiply the index to the right with the index to the left
            //in the resultant array
            res[i] = (mystack.isEmpty()) ? res[i]*0 : res[i]*(mystack.peek()+1);
            mystack.push(i);
        }
    }
     
    //function to return the max value in the resultant array
    int maxProduct(int[] arr,int[] res) {
        nextGreaterToLeft(arr,res);        //to find left max
        nextGreaterToRight(arr,res);    //to find right max
 
        int max = res[0];
        for(int i = 1;i


Python3
# Python3 program to find max LR product
mystack = []
       
# To find greater element to left
def nextGreaterToLeft(arr, res):
    mystack.append(0)
    res[0] = 0
       
    # iterate through the array
    for i in range(1, len(arr)):
        while(len(mystack) > 0  and arr[mystack[-1]] <= arr[i]):
            mystack.pop()
           
        # place the index to the left in the resultant array
        if (len(mystack) == 0):
            res[i] = 0
        else:
            res[i] = mystack[-1]+1
        mystack.append(i)
   
# To find greater element to right
def nextGreaterToRight(arr, res):
    mystack = []
       
    n = len(arr)
    mystack.append(n-1)
    res[n-1] *= 0
       
    # iterate through the array in the reverse order
    for i in range(n - 2, -1, -1):
        while(len(mystack) > 0  and arr[mystack[-1]] <= arr[i]):
            mystack.pop()
           
        # multiply the index to the right with the index to the left
        # in the resultant array
        if (len(mystack) == 0):
            res[i] = res[i]*0
        else :
            res[i] = res[i]*(mystack[-1]+1)
        mystack.append(i)
   
# function to return the max value in the resultant array
def maxProduct(arr, res):
    nextGreaterToLeft(arr,res)       #to find left max
    nextGreaterToRight(arr,res)      #to find right max
 
    Max = res[0]
    for i in range(1, len(res)):
        Max = max(Max, res[i])
    return Max
 
  # Driver code
arr = [5, 4, 3, 4, 5]
res = [0]*(len(arr))
 
maxprod = maxProduct(arr, res)
print(maxprod)
 
# This code is contributed by mukesh07.


C#
// C# program to find max LR product
using System;
using System.Collections;
class GFG {
 
    static Stack mystack = new Stack();
      
    //To find greater element to left
    static void nextGreaterToLeft(int[] arr,int[] res) {
        mystack.Push(0);
        res[0] = 0;
          
        //iterate through the array
        for(int i=1;i 0  &&  arr[(int)mystack.Peek()] <= arr[i])
                mystack.Pop();
              
            //place the index to the left in the resultant array
            res[i] = (mystack.Count == 0) ? 0 : (int)mystack.Peek()+1;
            mystack.Push(i);
        }
    }
      
    ////To find greater element to right
    static void nextGreaterToRight(int[] arr,int[] res) {
        mystack = new Stack();
          
        int n = arr.Length;
        mystack.Push(n-1);
        res[n-1] *= 0;
          
        //iterate through the array in the reverse order
        for(int i = n - 2; i >= 0; i--) {
            while(mystack.Count == 0  &&  arr[(int)mystack.Peek()] <= arr[i])
                mystack.Pop();
              
            //multiply the index to the right with the index to the left
            //in the resultant array
            res[i] = (mystack.Count == 0) ? res[i]*0 : res[i]*((int)mystack.Peek()+1);
            mystack.Push(i);
        }
    }
      
    //function to return the max value in the resultant array
    static int maxProduct(int[] arr,int[] res) {
        nextGreaterToLeft(arr, res);        //to find left max
        nextGreaterToRight(arr, res);    //to find right max
  
        int max = res[0];
        for(int i = 1; i < res.Length; i++){
            max = Math.Max(max, res[i]);
        }
        return max;
    }
     
  static void Main() {
    int[] arr = {5, 4, 3, 4, 5};
    int[] res = new int[arr.Length];
      
    int maxprod = maxProduct(arr, res);
    Console.WriteLine(maxprod);
  }
}
 
// This code is contributed by divyeshrabadiya07.


Javascript


输出:
8

方法二:减少使用的空间,只用一个数组存储左右最大值。

方法:

先决条件:https://www.geeksforgeeks.org/next-greater-element/

  • 为了找到左边的下一个更大的元素,我们使用了从左边开始的堆栈,并且相同的堆栈用于将右侧最大元素索引与左侧最大元素索引相乘。
  • 函数maxProduct( ) 用于通过迭代结果数组来返回最大产品。

C++

// C++ program to find max LR product
#include 
using namespace std;
 
stack mystack;
      
// To find greater element to left
void nextGreaterToLeft(int arr[], int res[], int N) {
    mystack.push(0);
    res[0] = 0;
      
    // iterate through the array
    for(int i = 1; i < N; i++) {
        while(mystack.size() > 0  &&  arr[mystack.top()] <= arr[i])
            mystack.pop();
          
        // place the index to the left in the resultant array
        res[i] = (mystack.size() == 0) ? 0 : mystack.top()+1;
        mystack.push(i);
    }
}
  
//// To find greater element to right
void nextGreaterToRight(int arr[], int res[], int N) {
    mystack = stack();
      
    int n = N;
    mystack.push(n-1);
    res[n-1] *= 0;
      
    // iterate through the array in the reverse order
    for(int i=n - 2 ; i >= 0; i--) {
        while(mystack.size() > 0  &&  arr[mystack.top()] <= arr[i])
            mystack.pop();
          
        //multiply the index to the right with the index to the left
        //in the resultant array
        res[i] = (mystack.size() == 0) ? res[i]*0 : res[i]*(mystack.top()+1);
        mystack.push(i);
    }
}
  
//function to return the max value in the resultant array
int maxProduct(int arr[], int res[], int N) {
    nextGreaterToLeft(arr,res, N);        //to find left max
    nextGreaterToRight(arr,res, N);    //to find right max
 
    int Max = res[0];
    for(int i = 1; i < N; i++){
        Max = max(Max, res[i]);
    }
    return Max;
}
     
int main()
{
    int arr[] = {5, 4, 3, 4, 5};
    int N = sizeof(arr) / sizeof(arr[0]);
    int res[N];
      
    int maxprod = maxProduct(arr, res, N);
    cout << maxprod << endl;
 
    return 0;
}
 
// This code is contributed by decode2207.

Java

//java program to find max LR product
 
import java.util.*;
 
public class GFG {
    Stack mystack = new Stack<>();
     
    //To find greater element to left
    void nextGreaterToLeft(int[] arr,int[] res) {
        mystack.push(0);
        res[0] = 0;
         
        //iterate through the array
        for(int i=1;i=0;i--) {
            while(!mystack.isEmpty()  &&  arr[mystack.peek()] <= arr[i])
                mystack.pop();
             
            //multiply the index to the right with the index to the left
            //in the resultant array
            res[i] = (mystack.isEmpty()) ? res[i]*0 : res[i]*(mystack.peek()+1);
            mystack.push(i);
        }
    }
     
    //function to return the max value in the resultant array
    int maxProduct(int[] arr,int[] res) {
        nextGreaterToLeft(arr,res);        //to find left max
        nextGreaterToRight(arr,res);    //to find right max
 
        int max = res[0];
        for(int i = 1;i

Python3

# Python3 program to find max LR product
mystack = []
       
# To find greater element to left
def nextGreaterToLeft(arr, res):
    mystack.append(0)
    res[0] = 0
       
    # iterate through the array
    for i in range(1, len(arr)):
        while(len(mystack) > 0  and arr[mystack[-1]] <= arr[i]):
            mystack.pop()
           
        # place the index to the left in the resultant array
        if (len(mystack) == 0):
            res[i] = 0
        else:
            res[i] = mystack[-1]+1
        mystack.append(i)
   
# To find greater element to right
def nextGreaterToRight(arr, res):
    mystack = []
       
    n = len(arr)
    mystack.append(n-1)
    res[n-1] *= 0
       
    # iterate through the array in the reverse order
    for i in range(n - 2, -1, -1):
        while(len(mystack) > 0  and arr[mystack[-1]] <= arr[i]):
            mystack.pop()
           
        # multiply the index to the right with the index to the left
        # in the resultant array
        if (len(mystack) == 0):
            res[i] = res[i]*0
        else :
            res[i] = res[i]*(mystack[-1]+1)
        mystack.append(i)
   
# function to return the max value in the resultant array
def maxProduct(arr, res):
    nextGreaterToLeft(arr,res)       #to find left max
    nextGreaterToRight(arr,res)      #to find right max
 
    Max = res[0]
    for i in range(1, len(res)):
        Max = max(Max, res[i])
    return Max
 
  # Driver code
arr = [5, 4, 3, 4, 5]
res = [0]*(len(arr))
 
maxprod = maxProduct(arr, res)
print(maxprod)
 
# This code is contributed by mukesh07.

C#

// C# program to find max LR product
using System;
using System.Collections;
class GFG {
 
    static Stack mystack = new Stack();
      
    //To find greater element to left
    static void nextGreaterToLeft(int[] arr,int[] res) {
        mystack.Push(0);
        res[0] = 0;
          
        //iterate through the array
        for(int i=1;i 0  &&  arr[(int)mystack.Peek()] <= arr[i])
                mystack.Pop();
              
            //place the index to the left in the resultant array
            res[i] = (mystack.Count == 0) ? 0 : (int)mystack.Peek()+1;
            mystack.Push(i);
        }
    }
      
    ////To find greater element to right
    static void nextGreaterToRight(int[] arr,int[] res) {
        mystack = new Stack();
          
        int n = arr.Length;
        mystack.Push(n-1);
        res[n-1] *= 0;
          
        //iterate through the array in the reverse order
        for(int i = n - 2; i >= 0; i--) {
            while(mystack.Count == 0  &&  arr[(int)mystack.Peek()] <= arr[i])
                mystack.Pop();
              
            //multiply the index to the right with the index to the left
            //in the resultant array
            res[i] = (mystack.Count == 0) ? res[i]*0 : res[i]*((int)mystack.Peek()+1);
            mystack.Push(i);
        }
    }
      
    //function to return the max value in the resultant array
    static int maxProduct(int[] arr,int[] res) {
        nextGreaterToLeft(arr, res);        //to find left max
        nextGreaterToRight(arr, res);    //to find right max
  
        int max = res[0];
        for(int i = 1; i < res.Length; i++){
            max = Math.Max(max, res[i]);
        }
        return max;
    }
     
  static void Main() {
    int[] arr = {5, 4, 3, 4, 5};
    int[] res = new int[arr.Length];
      
    int maxprod = maxProduct(arr, res);
    Console.WriteLine(maxprod);
  }
}
 
// This code is contributed by divyeshrabadiya07.

Javascript


输出
8

时间复杂度: O(n)