单调栈通用思路
引言
单调栈往往比较抽象,无论是栈头到栈底,还是从左到右,往往是记不住、易混淆递增递减关系,尤其是有时候数右边第一个大的数,有时候数左边第一个大的数。
其实从更抽象的角度来看,可以把栈看作已经遍历好的数,i是当前遍历的数,跳出栈内的递增或递减关系。
什么是单调栈?一句话说清核心
单调栈本质是用栈来维护一组**【有单调关系的已遍历元素】**。它的核心作用是:在遍历过程中,通过栈顶元素和当前元素的对比,快速找到「之前元素」和「当前元素」的大小关系,从而高效解决「下一个更大 / 更小元素」这类问题。
以找下一个更大元素为例
拿例子 nums = [73, 74, 75, 71, 71, 72, 76, 73] 来说,我们要找每个元素右边第一个比它大的元素。
如果需要找比当前元素大的元素,从栈的角度来看,栈中存放了当前遍历的i之前的信息。
- 如果i 比栈顶元素大,说明之前的元素(现已在栈内)找到了该元素(i,下一个比它大的元素),而且i还可能比栈内其他元素也大;
- 如果i 比栈内元素小,则说明i不是要找的元素。
关键是理解从栈存放的是已遍历过的元素,i是当前遍历的元素,可以弱化对栈头到栈顶是递增还是递减的判断,可以先假设栈内元素一定维护某个关系且一定是遍历之前的元素,所以就可以得到当前元素i和栈顶的关系,以及对应的操作。
题目清单
下面是力扣中有关单调栈的几个经典题目,数字表示力扣编号,链接是简单记录。
力扣-单调栈-739 每日温度
力扣-单调栈-503 下一个更大的元素Ⅱ
力扣-单调栈-42 接雨水
力扣-单调栈-84 柱状图中最大的矩形