滑动窗口中位数

中位数是有序序列最中间的那个数。如果序列的大小是偶数,则没有最中间的数;此时中位数是最中间的两个数的平均数。

例如:

[2,3,4],中位数是 3

[2,3],中位数是 (2 + 3) / 2 = 2.5

给出一个数组 nums,有一个大小为 k 的窗口从最左端滑动到最右端。窗口中有 k 个数,每次窗口移动 1 位。你的任务是找出每次窗口移动后得到的新窗口中元素的中位数,并输出由它们组成的数组。

例如:

给出 nums = [1,3,-1,-3,5,3,6,7],以及 k = 3。

窗口位置 中位数

--------------- -----

[1 3 -1] -3 5 3 6 7 1

1 [3 -1 -3] 5 3 6 7 -1

1 3 [-1 -3 5] 3 6 7 -1

1 3 -1 [-3 5 3] 6 7 3

1 3 -1 -3 [5 3 6] 7 5

1 3 -1 -3 5 [3 6 7] 6

因此,返回该滑动窗口的中位数数组 [1,-1,-1,3,5,6]。

提示:
假设k是合法的,即:k 始终小于输入的非空数组的元素个数.

解题思想

题目会给一个数组,和一个滑动窗口的大小K,让你找出当这个窗口滑动的过程中,这个K的窗口内的中位数分别是多少?

最naive的方式就是在k个窗口内排序就好,这里不解释(因为开销很大啊,(n-k+1) * (k*log(k))。。

这里的方法是使用两个优先队列,即出队列的顺序是按照某种排好序的方式进行的。

所以我们设立两个优先队列,这里叫做堆吧:

1、最大堆,值大的先出来

2、最小堆:值小的先出来

那么回到我们的问题,我们想想如何确定中位数:

1、假设我们有上述最大堆,最小堆

2、如果我们把进入的所有值较小的一半放到最大堆,较大的一半放到最小堆中,那么较小的那一半poll出来的,和较大那一半poll出来的,不正好是k个窗口的中位数的候选值么?

3、按照上面那个思想,我们就行动,再输入值得时候,根据其大小,放入最大堆或者最小堆中,然后调整一些大小,保证最大堆那边的大小等于或者多一个于最小堆

4、当输出的时候,也就是从最大堆取一个,或者双方各取一个就可以计算了

5、删除的时候,在对应的堆中删除,再按照3中的方式更新下就好

 import java.util.Collections;
import java.util.PriorityQueue; public class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
int n = nums.length;
int m = n - k + 1;
// 结果的尺寸
double[] res = new double[m];
//两个堆,一个最大堆,一个最小
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(k, Collections.reverseOrder());
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(k);
for (int i = 0; i<n; i++){
int num = nums[i];
// 让maxHeap始终保存小于一半的值,minHeap保存大于一半的,正好两半
if( maxHeap.size() == 0 || maxHeap.peek() >= num) maxHeap.add(num);
else minHeap.add(num);
// 维护两个堆,保证两个堆得大小,要么保持一致(偶数时),要么maxHeap多一个(奇数时)
if( minHeap.size() > maxHeap.size() ) maxHeap.add(minHeap.poll());
if( maxHeap.size() > minHeap.size() + 1 ) minHeap.add(maxHeap.poll());
// 如果需要输出
if ( i-k+1 >=0 ){
if( k % 2 == 1 ) res[i- k + 1] = maxHeap.peek();
else res[i- k + 1] = (maxHeap.peek()/2.0 + minHeap.peek()/2.0);
// 小心溢出
// 移除并更新
int toBeRemove = nums[i - k + 1];
if( toBeRemove <= maxHeap.peek()) maxHeap.remove(toBeRemove);
else minHeap.remove(toBeRemove);
// 维护两个堆,保证两个堆得大小,要么保持一致(偶数时),要么maxHeap多一个(奇数时)
if( minHeap.size() > maxHeap.size() ) maxHeap.add(minHeap.poll());
if( maxHeap.size() > minHeap.size() + 1 ) minHeap.add(maxHeap.poll());
}
}
return res;
}
}

Leetcode 480.滑动窗口中位数的更多相关文章

  1. Java实现 LeetCode 480 滑动窗口中位数

    480. 滑动窗口中位数 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 ...

  2. LeetCode295-Find Median from Data Stream && 480. 滑动窗口中位数

    中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操 ...

  3. 【LeetCode】480. 滑动窗口中位数 Sliding Window Median(C++)

    作者: 负雪明烛 id: fuxuemingzhu 公众号: 每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,中位数,multiset,刷题群 目录 题目描述 题目大意 解题方 ...

  4. 【Leetcode 二分】 滑动窗口中位数(480)

    题目 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) / 2 ...

  5. [LeetCode] Sliding Window Median 滑动窗口中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  6. 【leetcode 239. 滑动窗口最大值】解题报告

    思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...

  7. Leetcode 239.滑动窗口最大值

    滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...

  8. leetcode 239. 滑动窗口最大值(python)

    1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...

  9. leetcode全部滑动窗口题目总结C++写法(完结)

    3. 无重复字符的最长子串 A: 要找最长的无重复子串,所以用一个map保存出现过的字符,并且维持一个窗口,用le和ri指针标识.ri为当前要遍历的字符,如果ri字符在map中出现过,那么将le字符从 ...

随机推荐

  1. webm视频转换 其他视频格式转换为webm格式

    将其他视频格式转换为webm格式 https://files.cnblogs.com/files/bubuchu/html5videoshipingeshizhuanhuanqi.zip

  2. Objective-C Inheritance

    One of the most important concepts in object-oriented programming is that of inheritance. Inheritanc ...

  3. Linux下端口被占用如何解决???

    有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln netstat -tln | g ...

  4. SQL 中的group by (转载)

    概述 原始表 简单Group By Group By 和 Order By Group By中Select指定的字段限制 Group By All Group By与聚合函数 Having与Where ...

  5. .NET 读取视频文件

    该篇文章 复制别人的文章 在.NET中处理视频是一件痛苦的事情,.NET并没有提供视频处理的类.于是咱们只能找一些第三方的类库或者自己实现,在项目时间比较赶的情况下,自己实现是不可能的了,而且说不定会 ...

  6. POJ 1185 炮兵阵地 (状压DP,轮廓线DP)

    题意: 给一个n*m的矩阵,每个格子中有'P'或者'H',分别表示平地和高原,平地可以摆放大炮,而大炮的攻击范围在4个方向都是2格(除了自身位置),攻击范围内不能有其他炮,问最多能放多少个炮?(n&l ...

  7. URAL 1057 Amount of Degrees (数位DP,入门)

    题意: 求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的,B的整数次幂之和.例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足了要求:  17 = 24+2 ...

  8. 新萝卜家园GHOST WIN7系统32,64位官方版下载

    来自系统妈:http://www.xitongma.com 新萝卜家园GHOST win7系统64位官方经典版 V2016年3月 系统概述 新萝卜家园ghost win7系统64位官方经典版加快“网上 ...

  9. 小技巧:unicode RLO

    unicode 控制字符 RLO 可以将位于其后的文字翻转. 于是可以被病毒利用. 如图 重命名文件,在gpj前插入unicode RLO,之后若不小心,可能会被欺骗,误以为是jpg文件. 如果修改程 ...

  10. 《毛毛虫组》【Alpha】Scrum meeting 5

    第二天 日期:2019/6/18 1.1 今日完成任务情况以及遇到的问题. 今日完成任务情况: 出入库货物年统计模块设计及系统的测试运行: (1)对数据库表--tb_InStore和tb_OutSto ...