数据结构与算法之 leetcode 栈单调栈 数组下一个更大元素

数据结构与算法阿木 发布于 2 天前 1 次阅读


栈与单调栈:数组中下一个更大元素的解决方案

在数据结构与算法领域,栈是一种非常基础且重要的数据结构。它遵循后进先出(LIFO)的原则,广泛应用于各种算法实现中。单调栈是栈的一种特殊形式,它利用栈的特性来处理特定类型的序列问题,如数组中下一个更大元素的问题。本文将围绕这一主题,深入探讨单调栈的原理、实现以及在实际问题中的应用。

栈的基本概念

栈是一种线性数据结构,它支持两种基本操作:push(入栈)和pop(出栈)。当元素入栈时,它被放置在栈顶;当元素出栈时,栈顶的元素首先被移除。栈的这种特性使得它非常适合处理需要后进先出顺序的问题。

单调栈的定义

单调栈是一种特殊的栈,它维护一个单调递增或递减的序列。在单调递增栈中,栈顶元素总是比栈中其他元素大;在单调递减栈中,栈顶元素总是比栈中其他元素小。

单调栈在数组中下一个更大元素问题中的应用

数组中下一个更大元素问题是一个经典的面试题,其问题描述如下:

给定一个非空数组 `nums`,返回一个数组 `result`,其中 `result[i]` 是 `nums[i]` 的下一个更大元素。如果不存在下一个更大元素,则对应位置为 `-1`。

例如,对于输入数组 `[2, 1, 4, 3]`,输出数组应为 `[4, -1, 4, -1]`,因为 `2` 的下一个更大元素是 `4`,`1` 没有下一个更大元素,`4` 的下一个更大元素是 `4`,`3` 没有下一个更大元素。

单调栈可以高效地解决这个问题。以下是使用单调递减栈解决该问题的步骤:

1. 初始化一个空的单调递减栈和一个长度与原数组相等的输出数组 `result`,其中所有元素初始化为 `-1`。

2. 遍历原数组 `nums`,对于每个元素 `num`:

- 当栈不为空且栈顶元素 `top` 小于 `num` 时,说明 `num` 是栈顶元素 `top` 的下一个更大元素。

- 将 `num` 赋值给 `result[top]`。

- 从栈中移除元素 `top`。

- 将当前元素 `num` 入栈。

3. 遍历完成后,`result` 数组即为所求。

代码实现

以下是用 Python 实现的数组中下一个更大元素的解决方案:

python

def next_greater_elements(nums):


stack = []


result = [-1] len(nums)


for i in range(len(nums)):


while stack and stack[-1] < nums[i]:


result[stack.pop()] = nums[i]


stack.append(i)


return result

示例


nums = [2, 1, 4, 3]


print(next_greater_elements(nums)) 输出: [4, -1, 4, -1]


性能分析

单调栈解决数组中下一个更大元素问题的算法时间复杂度为 O(n),其中 n 是数组的长度。这是因为每个元素最多只会被压入和弹出栈一次。空间复杂度为 O(n),用于存储输出数组 `result`。

总结

单调栈是一种强大的工具,可以用来解决许多与序列相关的问题。在数组中下一个更大元素问题中,单调栈通过维护一个单调递减的序列,有效地找到了每个元素的下一个更大元素。通过理解单调栈的原理和实现,我们可以更好地掌握这一数据结构,并在实际编程中灵活运用。