单调栈是一种特殊的栈,它保证了栈中元素的顺序要么始终单调递增,要么始终单调递减。通过使用单调栈,我们可以高效地解决一些与区间最大值或最小值相关的问题。本文将详细介绍单调栈的概念、原理以及如何用它来解决区间最大值和最小值问题。
单调栈的概念
单调栈是一种特殊的栈,它保证了栈中元素的顺序。单调递增栈要求栈中元素从底到顶递增,而单调递减栈则要求栈中元素从底到顶递减。
单调栈的原理
单调栈的原理基于以下两个性质:
- 性质一:当栈为空或栈顶元素小于(或大于)当前元素时,将当前元素压入栈中。
- 性质二:当栈顶元素大于(或小于)当前元素时,弹出栈顶元素。
通过这两个性质,单调栈可以保持栈中元素的有序性,从而在处理问题时能够快速找到最大值或最小值。
单调栈解决区间最大值问题
假设我们有一个数组 arr,我们需要找到数组中每个子数组的最大值。
步骤:
- 创建一个空的单调递增栈。
- 遍历数组
arr,对于每个元素arr[i]:- 当栈为空或
arr[i]大于栈顶元素时,将arr[i]压入栈中。 - 当
arr[i]小于栈顶元素时,弹出栈顶元素,并将弹出的元素作为当前子数组的最大值。
- 当栈为空或
- 将栈中剩余的元素依次弹出,并将弹出的元素作为当前子数组的最大值。
代码示例:
def max_in_subarrays(arr):
stack = []
max_values = []
for i, num in enumerate(arr):
while stack and num > stack[-1]:
stack.pop()
stack.append(num)
max_values.append(stack[-1])
return max_values
单调栈解决区间最小值问题
假设我们有一个数组 arr,我们需要找到数组中每个子数组的最小值。
步骤:
- 创建一个空的单调递减栈。
- 遍历数组
arr,对于每个元素arr[i]:- 当栈为空或
arr[i]小于栈顶元素时,将arr[i]压入栈中。 - 当
arr[i]大于栈顶元素时,弹出栈顶元素,并将弹出的元素作为当前子数组的最小值。
- 当栈为空或
- 将栈中剩余的元素依次弹出,并将弹出的元素作为当前子数组的最小值。
代码示例:
def min_in_subarrays(arr):
stack = []
min_values = []
for i, num in enumerate(arr):
while stack and num < stack[-1]:
stack.pop()
stack.append(num)
min_values.append(stack[-1])
return min_values
总结
通过使用单调栈,我们可以轻松地解决区间最大值和最小值问题。单调栈的原理简单,但应用广泛,是算法学习中不可或缺的一部分。希望本文能帮助你更好地理解单调栈及其应用。
