问题描述
小R最近遇到了一个数组问题。他有一个包含 NN 个元素的数组,记作 a1,a2,...,aNa1,a2,...,aN。为了分析这个数组的特性,小R定义了两个函数 L(i)L(i) 和 R(i)R(i),并希望通过这两个函数来找到一些有趣的结论。
- L(i)L(i) 是满足以下条件的最大的 jj 值:
- j<ij<i
- a[j]>a[i]a[j]>a[i]
- 如果找不到这样的 jj,那么 L(i)=0L(i)=0;如果有多个满足条件的 jj,选择离 ii 最近的那个。
- R(i)R(i) 是满足以下条件的最小的 kk 值:
- k>ik>i
- a[k]>a[i]a[k]>a[i]
- 如果找不到这样的 kk,那么 R(i)=0R(i)=0;如果有多个满足条件的 kk,选择离 ii 最近的那个。
最终,小R定义 MAX(i)=L(i)∗R(i)MAX(i)=L(i)∗R(i),他想知道在 1≤i≤N1≤i≤N 的范围内,MAX(i)MAX(i) 的最大值是多少。
解题代码
public class Main {
public static int solution(int n, int[] array) {
// Edit your code here
int[] L = new int[n];
int[] R = new int[n];
// Initialize L and R arrays
for (int i = 0; i < n; i++) {
L[i] = 0;
R[i] = 0;
}
// Calculate L[i] using stack
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && array[stack.peek()] <= array[i]) {
stack.pop();
}
L[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
stack.push(i);
}
// Clear the stack for R[i] calculation
stack.clear();
// Calculate R[i] using stack
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && array[stack.peek()] <= array[i]) {
stack.pop();
}
R[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
stack.push(i);
}
// Calculate maxProduct
int maxProduct = 0;
for (int i = 0; i < n; i++) {
maxProduct = Math.max(maxProduct, L[i] * R[i]);
}
return maxProduct;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(5, new int[]{5, 4, 3, 4, 5}) == 8);
}
}
知识点分析
栈
栈(Stack)是一种抽象数据类型,它遵循后进先出(LIFO, Last In First Out)的原则。这意味着最后被添加到栈中的元素将首先被移除。栈在计算机科学中是一种非常常见的数据结构,用于解决各种问题,如函数调用管理、表达式求值、回溯算法等。
栈通常具有以下基本操作:
Push:将一个元素添加到栈的顶部。
Pop:移除并返回栈顶部的元素。如果栈为空,则此操作可能导致错误或异常。
Peek(或 Top):返回栈顶部的元素,但不移除它。如果栈为空,则此操作可能导致错误或异常。
IsEmpty:检查栈是否为空。如果栈为空,则返回 True;否则,返回 False。
Size:返回栈中元素的数量。
栈可以通过数组、链表或其他数据结构来实现。在实际应用中,栈通常用于实现其他复杂的数据结构和算法,如队列、图的深度优先搜索(DFS)等。