题目
labuladong way
单调队列
1 | class MonotonicQueue { |
不同于一般最大单调栈之处:
- 只需求滑窗k里面的最大的一个值出来,也就意味着求出最大的max之后,max之前的所有元素可以丢掉了.
- 仅在
滑窗大小 < k时,元素才需push入栈。
References
https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
Just a Blog
1 | class MonotonicQueue { |
不同于一般最大单调栈之处:
滑窗大小 < k时,元素才需push入栈。https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
1 | class StockSpanner { |
单调栈模板的伪代码:
1 | Stack stack = new Stack(); |
问题在于,因为单调栈是要把元素都丢弃的,状态都被“折叠”了,我们会丢失长度,所以容易想到,我们需要cache一下之前栈内元素被折叠的长度 cache有很多种方式,可以用hash表等数据结构,也可以用动态规划 但这题的更优解是,使用另一个同步栈来缓存,读者可以根据下面第一版的代码,动笔推导一下折叠过程,就能体会同步栈工作的原理了。
都说编程旷世难题是取名字,名字取好了,问题也就解决了一半(才怪 我们可以将两个栈分别命名为 prices 和 cache
然后就有了下面初版的代码
我们如果发现插入元素满足本身栈的递减需求,则直接返回1,因为该值前一个值是比它大的 如果不满足,则开始折叠,并将栈中,值比它小的所有段落都累计起来,再将自己插入栈中即可
https://leetcode-cn.com/problems/online-stock-span/solution/gu-piao-jie-ge-kua-du-by-leetcode/
单调栈模板的伪代码:
1 | Stack stack = new Stack(); |
https://leetcode-cn.com/problems/online-stock-span/solution/dan-diao-zhan-tao-lu-xie-fa-you-hua-wei-guan-fang-/
1 | class Solution { |
但是发现时间/空间复杂度都很低,
元素和右边最大(小)元素都用tuple存放在一个容器内。优化代码结构后:
1 | class Solution { |
https://leetcode-cn.com/problems/daily-temperatures/solution/mei-ri-wen-du-by-leetcode/
1 | vector<int> nextGreaterElements(vector<int>& nums) |
通过索引翻倍-1 和 %运算,来达到模拟数组中元素翻倍的效果。
1 | // 假装这个数组长度翻倍了 |
同时,在元素出栈后,对栈空状态进行判断,
res对应值为-1res对应值为ntuple的容器的空间大小https://leetcode-cn.com/problems/next-greater-element-ii/solution/dan-diao-zhan-jie-jue-next-greater-number-yi-lei-2/
1 | class Solution { |
数组中元素依次进栈:
tupleunordered_map中来tuple的容器这是一个很经典的单调栈题。
https://leetcode-cn.com/problems/next-greater-element-i/solution/xia-yi-ge-geng-da-yuan-su-i-by-leetcode/
1 | class Solution { |
让数组中元素依次进栈:
假如栈空,元素直接进栈;
假如栈顶top元素小于数组cur元素,则将数组内元素依次弹出直至:
栈顶元素大于数组cur元素
栈空
若栈顶元素pop()后且此时栈不为空,
dist = cur - s.top() - 1;,
bounded_height = min(height[s.top()], height[cur]) - height[top];
ans += dist * bounded_height;
由此累加cur元素到top元素的矩形长度进ans;
假如数组中无元素,则对栈中元素依次出栈;
PS:在这里是对数组的索引进行进栈操作,而不是具体到元素。
1 | /** |
非递归实现DFS遍历 + 带 树高 状态
1 | class Solution { |
1 | /** |
非递归实现BFS遍历 + 带 树高 状态
我的思路是先得到满足要求的节点,再重新构建二叉搜索树,不过显然不是最优解。
1 | class Solution { |
剪枝思路:
root->val < L,
root及左孩子剪枝,右孩子提升为root
root->val > R
root及右孩子剪枝,左孩子提升为root
L <= root->val && root->val <= R
不需要对root剪枝,递归调用左右孩子
https://leetcode-cn.com/problems/trim-a-binary-search-tree/solution/xiu-jian-er-cha-sou-suo-shu-by-leetcode/