Monotonic-stack
单调栈可以用来求在一个数组中,位置i
上的数左右离它最近的且比i位置上的数大(或小)的第一个数。首先,如果要求最近且比位置i
上的数大,那么就要维持一个从栈底到栈顶由大到小的状态。如果新进来的数大于栈顶的数,那么栈顶数x
右边最大的数就是即将新进来的数。x
左边的最大的数就是栈顶地下的数。(这适用于数组中没有重复的数字)。
如果有重复值,那么栈中就不存放下标了,存放一个数组(保存的是大小相同的元素下标),每次弹出时,左边最近比它的是它下边队列后的最后一个下标位置的元素。
``` c++ "数组中无重复元素" //单调栈结构,求解i位置上左右离他最近且比它小的值 struct MonotonicStack { stack mono; //返回一个二维数组,每一行表示该位置左右离它最近的数,0左1右 vector> GetNearLessNoRepeat(vector& nums) { if (nums.empty()) { return vector> {}; } //一定要先开辟空间,否则无法使用下标 vector> results(nums.size(),vector(2)); //处理每个位置上的元素 for (int i = 0; i < (int)nums.size(); ++i) { //单调栈,栈底到栈顶,由小到大 while (!mono.empty() && nums[mono.top()] > nums[i]) { //栈不空,且栈顶元素比即将入栈的元素大,破坏了有大到小的结构(从栈顶到栈底) int current = mono.top(); mono.pop(); results[current][1] = i; results[current][0] = mono.empty() == true ? -1 : mono.top(); } //栈不为空且栈顶元素小于nums[i] mono.push(i); } //如果栈不为空,还需结算处理 while (!mono.empty()) { int popIndex = mono.top(); mono.pop(); results[popIndex][1] = -1; results[popIndex][0] = mono.empty() == true ? -1 : mono.top(); } return std::move(results); }
Last updated
Was this helpful?