左右下一个较大的索引的最大乘积
给定一个数组 a[1..N]。对于位置 i (1 <= i <= N) 处的每个元素。在哪里
- L(i)被定义为最接近的索引 j,使得 j < i 并且 a[j] > a[i]。如果不存在这样的 j 则L(i) = 0 。
- R(i)被定义为最接近的索引 k,使得 k > i 并且 a[k] > a[i]。如果不存在这样的 k 则R(i) = 0 。
LRProduct(i) = L(i)*R(i) 。
我们需要找到一个具有最大 LRProduct 的索引
例子:
Input : 1 1 1 1 0 1 1 1 1 1
Output : 24
For {1, 1, 1, 1, 0, 1, 1, 1, 1, 1} all element are same except 0. So only for zero their exist greater element and for others it will be zero. for zero, on left 4th element is closest and greater than zero and on right 6th element is closest and greater. so maximum
product will be 4*6 = 24.
Input : 5 4 3 4 5
Output : 8
For {5, 4, 3, 4, 5}, L[] = {0, 1, 2, 1, 0} and R[]
= {0, 5, 4, 5, 0},
LRProduct = {0, 5, 8, 5, 0} and max in this is 8.
注意:以起始索引为 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)