应用
往往用来遍历数组,找到数组中离某个元素最近的比它小或者比它大的值。O(n)的复杂度,一遍扫描。
当然也可以用来找一个元素两侧比它大或者比它小的元素长度(用它将要出栈时的当前元素下标i
减去它出栈后栈顶元素的下标j
再减1)。
方法
假如找某个元素左边离它最近的比它小的元素,那么我们要用单调递增的栈。从左到右扫描数组,假如当前元素arr[i]
比栈顶元素s.top()
小,则s.pop()
,直到栈为空或者arr[i] > s.top()
。
单调递增的栈内相邻的两个元素,假如它们在数组arr
中的下标为i
或j
,那么对于k > i && k < j
,arr[k] > arr[i] && arr[k] > arr[j]
. 也就是说单调递增的栈内相邻的两个元素类似山峰的两侧山脚,而且是左右高低不平的两个山脚。
单调递减的栈同理,找的是山谷两侧高低不平的山头。
模板
比较常见的是栈内存下标。
stack<int> s;
for(int i = 0; i < n; i++){
// 先pop再push
// check函数根据栈的单调性不同
while(!s.empty() && check(s.top(), i)){
s.pop();
}
s.push(i);
}