这个题只想到了暴力解法,但是超时了,答案是维护一个从小到大的单向队列,这个单项队列维护的是可能是最大值的一组数,把滑动窗口分成了两部分,减去左边边界,加上右边边界,在减去左边边界时要考虑到是否是队列中的最大值,即队列出口的值,就把最大值去掉,加上右边界就是从入口处开始判断,把队列中小于这个数的全部移除,每次遍历队列的出口即为答案数组的值,当时对这个方法表示怀疑是因为如果窗口内包含多个最大值,但是把队列中最大值移除后,新加右边界的值比原来的最大值小的话,队列的右边界就没办法输出正确的值了,后来想了一下,这个想法是多余的,因为每次往队列加数据的时候,可能有重复的值,把右边最大值去掉了,右边第二位可能放的跟第一位一样大的,就不会出现我这种担心情况。还有就是queue没想到用啥就用deque
这个题完全没思路,答案是用小顶堆做的,大顶堆和小丁堆其实就是一个完全二叉树,其区别是大顶堆是根节点大于其左右节点,小顶堆刚好相反,根节点小于左右节点,在java中,优先队列其底层就是顶堆,不会拼这个写三遍,PriorityQueue<int[]>queue=new PriorityQueue<>((O1,O2)->O1[1]-O2[1]),PriorityQueue<int[]>queue=new PriorityQueue<>(O1,O2->O1[1]-O2[1]),PriorityQueue<int[]>queue=new Priority<>((O1,O2)->O1[1]-O2[1]),思路是维护一个size为K的小顶堆,为什么选小顶对?
如果大顶堆,根节点为最大值,但是顶堆每次去除元素时都是从头开始的,最后只能得到频率最小的k个值,为了得到值对应的频率,只能用map进行存储,然后遍历这个map,把遍历到的元素新建int数组后,直接放入queue,如果queue的size大于k,就移除小顶堆最上面的值,因为要求按频率从大到小返回,而小顶堆每次poll都是较小的,跟需要的结果相反,那就i=k-1;i>=0;i--,通过将结果数组倒序填充,得到最后的答案