单调栈

90 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情


单调栈是一种常用的数据结构,其中的元素满足单调性。单调栈常用于解决一些复杂的问题,例如求最大子序列和、求最小生成树等。

单调栈的定义

单调栈是一种满足单调性的栈。它可以是单调递增栈或单调递减栈。单调栈中的元素满足其单调性,也就是说,当栈为单调递增栈时,栈顶元素是栈中所有元素的最大值;当栈为单调递减栈时,栈顶元素是栈中所有元素的最小值。

用途

单调栈常用于解决一些复杂的问题,例如求最大子序列和、求最小生成树等。在解决这些问题时,我们需要维护一个单调的序列,并根据需要在这个序列中进行插入、删除、查找等操作。单调栈正好可以满足这些需求,因此在解决这些问题时常常使用单调栈。

例子

举个例子,我们考虑使用单调栈来解决一个经典的问题:求最大子序列和。假设我们给定一个数组 A,我们希望求出其中的一个子序列,使得这个子序列的和最大。

我们可以使用单调栈来解决这个问题。我们从前往后遍历数组 A,并维护一个单调递减栈。每当遇到一个新的数字时,我们就将其插入栈中。如果当前数字比栈顶元素大,我们就弹出栈顶元素,直到栈为空或者栈顶元素比当前数字大为止。这样,我们就保证了栈中的元素是单调递减的。

我们按照这样的方法遍历整个数组,最后得到的栈中的元素就是最大子序列。我们只需要将栈中的元素相加,就可以得到最大子序列的和。

再举一个例子,我们考虑使用单调栈来解决最小生成树问题。假设我们给定一个无向图,我们希望求出其中的一颗最小生成树。

我们可以使用单调栈来解决这个问题。我们从图中任意一个点开始,并维护一个单调递增栈。每当我们遍历到一条边时,我们就将其插入栈中。如果当前边的边权比栈顶元素的边权小,我们就弹出栈顶元素,直到栈为空或者栈顶元素的边权比当前边的边权小为止。这样,我们就保证了栈中的元素是单调递增的。

我们按照这样的方法遍历整个图,最后得到的栈中的元素就是最小生成树。我们只需要将栈中的元素加入生成树中,就可以得到最小生成树。