返回

强势来袭:单调栈算法——空间换时间的制胜法宝

闲谈

单调栈的本质——空间换时间

单调栈算法的核心思想是利用栈的数据结构,通过维护一个单调递增或递减的栈来存储数组元素,实现快速查找满足单调条件的元素位置。

当我们遍历数组时,如果当前元素满足单调条件(例如,对于递增栈,当前元素大于栈顶元素),则将当前元素压入栈中。如果当前元素不满足单调条件,则弹出栈顶元素,直到找到满足单调条件的元素为止。这样,栈中始终保持着满足单调条件的元素,我们就可以通过栈来快速查找任一元素的右边/左边第一个比自己大/小的元素的位置。

单调栈的应用场景

单调栈算法在计算机科学中有着广泛的应用,以下是一些常见的应用场景:

  • 求解最近较小值/较大值问题:单调栈可以用于求解最近较小值/较大值问题。例如,给定一个数组,找到每个元素左边第一个比自己小的元素和右边第一个比自己大的元素。
  • 求解最长递增子序列问题:单调栈可以用于求解最长递增子序列问题。例如,给定一个数组,找到数组中最长递增子序列的长度和子序列本身。
  • 求解最近较小值/较大值问题:单调栈可以用于求解最近较小值/较大值问题。例如,给定一个数组,找到每个元素左边第一个比自己小的元素和右边第一个比自己大的元素。

单调栈实例演示

为了更好地理解单调栈算法,我们通过一个具体的实例来演示其应用。

假设我们有一个数组[1, 3, 2, 4, 5, 2, 6, 1],现在我们想找到每个元素左边第一个比自己小的元素和右边第一个比自己大的元素。

我们使用一个单调递增栈来存储数组元素,栈中元素始终保持递增顺序。当我们遍历数组时,如果当前元素大于栈顶元素,则将当前元素压入栈中。如果当前元素小于栈顶元素,则弹出栈顶元素,直到找到一个小于当前元素的元素为止。这样,栈中始终保持着递增顺序,我们可以通过栈来快速查找每个元素左边第一个比自己小的元素和右边第一个比自己大的元素。

以下是如何使用单调栈算法解决此问题的步骤:

  1. 初始化一个空栈。
  2. 遍历数组元素。
  3. 如果当前元素大于栈顶元素,则将当前元素压入栈中。
  4. 如果当前元素小于栈顶元素,则弹出栈顶元素,直到找到一个小于当前元素的元素为止。
  5. 将当前元素的左边第一个比自己小的元素设置为栈顶元素。
  6. 将当前元素的右边第一个比自己大的元素设置为栈中下一个元素。
  7. 重复步骤2-6,直到遍历完整个数组。

通过上述步骤,我们可以得到每个元素左边第一个比自己小的元素和右边第一个比自己大的元素。

总结

单调栈算法是一种非常实用的算法,它可以在O(n)的时间复杂度内解决许多单调性问题。单调栈算法的本质是空间换时间,通过维护一个单调栈来存储数组元素,可以快速查找任一元素的右边/左边第一个比自己大/小的元素的位置。单调栈算法在计算机科学中有着广泛的应用,包括求解最近较小值/较大值问题、求解最长递增子序列问题、求解最近较小值/较大值问题等。