mono stack
最近在练习题目的时候经常遇到mono stack
的题目,总的来说题目还是非常非常的有意思,单调栈真心是个利器。可以解决非常多的复杂的问题。可以利用单调栈求出以当前值为最大值或者最小值的连续子数组的最大长度。
单调栈的原理
单调栈中的数据需要遵循两个原则:
- 栈中的数据会是严格递增或者递减,则我们可以知道,假如单调栈中的数据为递减,则可以知道栈顶的数据一定为当前序列中最大的数据;假如单调栈中的数据为递增,则可以知道栈顶的数据一定为当前序列中最小的数据。一般情况下我们都会用
dequeue
来处理单调栈的数据,则可以知道队列的头部一定为当前序列中所求的最大值或者最小值。 - 为了保持单调性,则每当加入一个新的元素时,则会将栈中所有比当前元素小或者大的数据全部进行出栈,则由此我们可以判断如下,假设当前的栈为递减:
从图中可以看出我们可以在$O(1)$的时间复杂度内求出当前序列的极值。栈中任意相邻的两个元素比如$(arr[i],arr[j])$,则表示所有处于$(i,j)$之间的元素均小于$arr[j]$,有了这个重要的推论,则许多问题都可以利用这个特性来求解,比如我们知道假设某个元素x
大于$arr[j]$,则表示x
一定大于所有位于$[i+1,j]$之间的元素。下面有几个非常有代表性的题目需要讨论下:
下一个更大元素 II
题目
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
地址
https://leetcode-cn.com/problems/next-greater-element-ii
题意
classical problem
思路
- 首先题目中要求循环处理,这个很简单我们只需要在数组后面对数组本身再进行重复复制一遍即可,这样我们即可完成循环处理。
- 最经典的处理莫过于如何求第一个比其小或者大的数的处理,我们利用单调栈,所有小于当前的数全部从栈中弹出,因为我们知道一个推论为,栈中任意相邻的两个元素比如$(arr[i],arr[j])$,则表示所有处于$(i,j)$之间的元素均小于$arr[j]$,此时我们即可利用单调性很快求出所有的值。
代码
class Solution { |
Longest Sublist with Value Range Condition
题目
Given a list of integers nums, return the length of the longest sublist where 2 * min(sublist) > max(sublist).
Constraints
n ≤ 100,000 where n is the length of nums
Example 1
Input
nums = [9, 1, 5, 5, 3, 3]
Output
4
Explanation
The sublist [5, 5, 3, 3] is the longest sublist that meet the criteria since 2 * 3 > 5.
地址
https://binarysearch.com/problems/Longest-Sublist-with-Value-Range-Condition
题意
双指针加单调栈
思路
- 这个题目更加经典,需要同时利用单调栈和双指针。
代码
int solve(vector<int>& nums) { |
qiu
题目
Given a set of arrays of size and an integer , you have to find the maximum integer for each and every contiguous subarray of size for each of the given arrays.
nput Format
First line of input will contain the number of test cases T. For each test case, you will be given the size of array N and the size of subarray to be used K. This will be followed by the elements of the array Ai.
Constraints, where is the element in the array .
Output Format
For each of the contiguous subarrays of size of each array, you have to print the maximum integer.
Sample Input
2 |
Sample Output
4 6 6 4 |
地址
https://www.hackerrank.com/challenges/deque-stl/problem
题意
单调栈 + 滑动窗口
思路
- 这个题目更加经典,需要同时利用单调栈和双指针。利用单调性,单调栈中的栈头一定保存的是当前序列的最大值。同时利用滑动窗口,一旦窗口超过队头的元素,则将队头的元素进行删除即可。
代码
|
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章