239. Sliding Window Maximum
思路
类似这种在某个valid value set里面取最值的题目其实很多, 比如218 city skyline问题的heap解法, 也是把当前有效(可用)的高度维护在堆中,
每次取最值.
同理, 本题我们用双端队列来维护当前所有的valid值. 每次检查队列内最早的元素坐标, 是否和当前坐标的距离大于k, 如果大于, (根据题意)需要扔掉(q.popleft()
).
然后要把已经在队列里的, 并且值比当前值小的也扔掉(q.pop()
), 因为当前的坐标的有效期(生命周期)肯定大于之前的, 所以如果当前值更大, 之前出现的比较小的值就没有存在于候选队列的必要了.
这样我们维护一个单调递减的队列, 每次可以O(1)
复杂度从队首q[0]
取最大值.
代码
1 | class Solution(object): |
无脑TreeMap:
1 | class Solution { |
1425. Constrained Subset Sum
思路
英文题目描述有点艰涩, 建议读中文描述. 我们要从一个数组中删除一些值(也可以不删), 要求删除操作之后的数组的相邻元素之间, 在原数组的距离不能大于k.
换种理解方式: 我们要从一个数组中按顺序取值, 但是每次取值的跳跃不能太远, 比如这次取了坐标i
处的值, 下次只能在[i+1, i+k]
闭区间内取, 不能更远. 求这样取出来的值的最大和.
和上一题几乎一模一样, 包装了一层DP的思想. 用一个单调(递减)队列维护当前有效的坐标, 其中对应最大的和的坐标位置在队首. 每次检查队首要不要扔掉.
代码
1 | class Solution(object): |
另外此题用Java的TreeMap/TreeSet也可解, 相当于TreeSet无脑替我们维护了最大值, 每次删除值的时候复杂度O(logn)
.
1 | class Solution {// From Cicindela |