单调栈是一种特殊的栈结构,它用于处理满足单调性质的元素序列。在单调栈中,元素按照其单调性(递增或递减)排列,并且保证了栈内元素的相对顺序。单调栈通常用于解决与下标有关的问题,如找到下一个或上一个更大的(或更小的)元素,或者处理与数组前缀和或后缀和相关的问题。
- 核心思想:
- 单调递增栈:栈底到栈顶的元素是单调递增的。
- 单调递减栈:栈底到栈顶的元素是单调递减的。
- 应用场景:
- Next Greater Element:找到每个元素右边的第一个更大的元素。
- Next Smaller Element:找到每个元素右边的第一个更小的元素。
- Longest Increasing Subsequence(最长递增子序列):找到最长的严格递增子序列。
- 最小/最大公共前缀:在多个字符串中找到共有的最短/最长公共前缀。
- 实现步骤:
- 初始化一个空栈。
- 遍历数组中的每个元素。
- 对于每个元素,执行以下操作:
- 如果栈为空,或者当前元素大于栈顶元素(对于单调递增栈),则将其推入栈中。
- 如果当前元素小于栈顶元素,从栈中弹出栈顶元素(这将违反单调性质),继续比较新的栈顶元素与当前元素,直到栈为空或当前元素大于等于栈顶元素。
- 栈中元素的顺序即为满足单调性质的顺序。
例题展示为:字节跳动算法岗面试题目
执行起到的作用是找到了以该数为最小值的字符区间
def max_min_sum_product(nums):
n = len(nums)
left = [-1] * n
right = [n] * n
# Calculate left boundary for each element
stack = []
for i in range(n):
while stack and nums[stack[-1]] >= nums[i]:
stack.pop()
if stack:
left[i] = stack[-1]
stack.append(i)
# Calculate right boundary for each element
stack = []
for i in range(n - 1, -1, -1):
while stack and nums[stack[-1]] >= nums[i]:
stack.pop()
if stack:
right[i] = stack[-1]
stack.append(i)
# Calculate max product
max_product = 0
for i in range(n):
min_value = nums[i]
sum_in_interval = sum(nums[left[i] + 1:right[i]])
max_product = max(max_product, min_value * sum_in_interval)
return max_product
n=int(input())
nums=list(map(int,input().split()))
result = max_min_sum_product(nums)
print(result) # 输出 36
# 示例用法
#nums = [6, 2, 1]
#result = max_min_sum_product(nums)
#print(result) # 输出 36
#给定一个数组序列, 需要求选出一个区间, 使得该区间是所有区间中经过如下计算的值最大的一个:
#区间中的最小数 * 区间所有数的和最后程序输出经过计算后的最大值即可,不需要输出具体的区间。如给定序列 [6 2 1]则根据上述公式, 可得到所有可以选定各个区间的计算值: