280. 239. 滑动窗口中位数/最大值 | 滑动窗口系列

分析:
这题最直观的解法,就是在数组中对窗口内的数字进行排序,然后计算中位数:

但是,暴力解法永远面临的一个问题就是时间复杂度过大,因此我们就需要针对窗口的删除、添加元素和排序进行优化。
首先肯定不能在窗口移动的时候进行排序,这样会浪费大量的时间,因此我们先在循环外部排好序,然后在每次窗口移动的时候,移除最左边的元素,往最右边添加一个元素。接着,对添加进来的元素进行排序,使窗口数组仍然有序。
因为vector已经是有序数组,所以不能直接删除第一个元素,而是要找到与nums[left]相同的那个元素,left指向的元素才是窗口最左边的元素。这里可以用二分查找法来找到这个元素,然后删除。

删除掉窗口最左边元素后,我们将新的元素添加进窗口,同时使窗口数组保持有序。这里可以直接用插入排序来插入新元素。在这题中,因为只需要插入一个元素,所以插入排序是优于快速排序的。

注意:
这里有个编译器上的坑,在vsCode等本地编译器上,当vector.size()=0的时候,调用vector.back()还是会返回一个数字,但是在力扣中国的编译器上,会提示错误,因此我们需要加入一个条件,判断当窗口为空的时候,直接添加元素。

除此之外,官方给出的标准答案是使用双堆来解题,以及c++独有的STL容器中的多重集合。
参考答案:
https://leetcode-cn.com/problems/sliding-window-median/solution/hua-dong-chuang-kou-zhong-wei-shu-by-leetcode/


这题和280是一样的,只需要把判断条件换成取最大值即可,即 res.push_back(window.back());
不过题目有个额外要求,就是看能不能把时间复杂度降到O(N), 我们之前的方法复杂度至少是O(NlogN),要降到O(N)一般都是使用动态规划来解答。