### 问题描述
小R最近遇到了一个数组问题。他有一个包含 𝑁N 个元素的数组,记作 𝑎1,𝑎2,...,𝑎𝑁a1,a2,...,aN。为了分析这个数组的特性,小R定义了两个函数 𝐿(𝑖)L(i) 和 𝑅(𝑖)R(i),并希望通过这两个函数来找到一些有趣的结论。
- 𝐿(𝑖)L(i) 是满足以下条件的最大的 𝑗j 值:
- 𝑗<𝑖j<i
- 𝑎[𝑗]>𝑎[𝑖]a[j]>a[i]
- 如果找不到这样的 𝑗j,那么 𝐿(𝑖)=0L(i)=0;如果有多个满足条件的 𝑗j,选择离 𝑖i 最近的那个。
- 𝑅(𝑖)R(i) 是满足以下条件的最小的 𝑘k 值:
- 𝑘>𝑖k>i
- 𝑎[𝑘]>𝑎[𝑖]a[k]>a[i]
- 如果找不到这样的 𝑘k,那么 𝑅(𝑖)=0R(i)=0;如果有多个满足条件的 𝑘k,选择离 𝑖i 最近的那个。
最终,小R定义 𝑀𝐴𝑋(𝑖)=𝐿(𝑖)∗𝑅(𝑖)MAX(i)=L(i)∗R(i),他想知道在 1≤𝑖≤𝑁1≤i≤N 的范围内,𝑀𝐴𝑋(𝑖)MAX(i) 的最大值是多少。
测试样例
样例1:
输入:
n = 5, array = [5, 4, 3, 4, 5]
输出:8
样例2:
输入:
n = 6, array = [2, 1, 4, 3, 6, 5]
输出:15
样例3:
输入:
n = 7, array = [1, 2, 3, 4, 5, 6, 7]
输出:0为了解决这个问题,我们需要为数组中的每个元素找到其左侧和右侧第一个比它大的元素的索引,然后计算这两个索引的乘积,并找到这些乘积中的最大值。
我们可以使用单调栈来高效地找到每个元素的左侧和右侧第一个比它大的元素。具体步骤如下:
-
初始化:创建两个数组
left和right,分别用于存储每个元素的左侧和右侧第一个比它大的元素的索引。初始值都为0。 -
找到左侧第一个比它大的元素:
- 使用一个单调递减的栈,从左到右遍历数组。
- 对于每个元素,如果栈顶元素的值大于当前元素,则栈顶元素的索引就是当前元素的左侧第一个比它大的元素的索引。
- 如果栈顶元素的值小于或等于当前元素,则弹出栈顶元素,继续比较,直到找到一个比当前元素大的元素或栈为空。
- 将当前元素的索引压入栈中。
-
找到右侧第一个比它大的元素:
- 使用一个单调递减的栈,从右到左遍历数组。
- 对于每个元素,如果栈顶元素的值大于当前元素,则栈顶元素的索引就是当前元素的右侧第一个比它大的元素的索引。
- 如果栈顶元素的值小于或等于当前元素,则弹出栈顶元素,继续比较,直到找到一个比当前元素大的元素或栈为空。
- 将当前元素的索引压入栈中。
-
计算乘积并找到最大值:
- 遍历
left和right数组,计算每个元素的L(i) * R(i),并找到这些乘积中的最大值。
- 遍历
def solution(n, array):
# 初始化 left 和 right 数组
left = [0] * n
right = [0] * n
# 填充 left 数组
stack = []
for i in range(n):
while stack and array[stack[-1]] <= array[i]:
stack.pop()
if stack:
left[i] = stack[-1] + 1
else:
left[i] = 0
stack.append(i)
# 填充 right 数组
stack = []
for i in range(n-1, -1, -1):
while stack and array[stack[-1]] <= array[i]:
stack.pop()
if stack:
right[i] = stack[-1] + 1
else:
right[i] = 0
stack.append(i)
# 计算 MAX(i) 并找到最大值
max_value = 0
for i in range(n):
max_value = max(max_value, left[i] * right[i])
return max_value
if __name__ == "__main__":
# Add your test cases here
print(solution(5, [5, 4, 3, 4, 5]) == 8)
print(solution(6, [2, 1, 4, 3, 6, 5]) == 15)
print(solution(7, [1, 2, 3, 4, 5, 6, 7]) == 0)