原题链接在这里:https://leetcode.com/problems/sliding-window-median/?tab=Description

题目:

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

Examples:

[2,3,4] , the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Your job is to output the median array for each window in the original array.

For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

Window position                Median
--------------- -----
[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

Therefore, return the median sliding window as [1,-1,-1,3,5,6].

Note: 
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

题解:

使用minHeap和maxHeap来维护median. 为了方便,这里始终保持minHeap.size() == maxHeap.size() 或 minHeap.size() = maxHeap.size()+1.

所以最开始两个heap都为空时,加到minHeap中.

取median时若size相同就两边peek求和除以2. 若size不同,那么肯定minHeap size大, minHeap peek下就是median.

remove时,看要remove的数nums[i-k], 若比median小,从maxHeap中remove. 不然从minHeap中remove.

Note: 两遍peek求和时注意overflow.

Remove时如果出现小数, 多半会从小的这一侧remove, 也就是maxHeap中remove. 所以添加时应该尽量向大的这一侧添加. 但添加时检测要用!maxHeap.isEmpty()&&maxHeap.peek()>nums[i]限制小的一侧添加, 而不用minHeap.isEmpty() || minHeap.peek()<nums[i]胡乱往大的一侧添加. 因为有可能minHeap刚才经过remove已经空了, 若出现个很小的数就错误的加进了minHeap中.

Time Complexity: O(nk), n = nums.length. 对于minHeap 和 maxHeap来说每个元素add, remove O(1)次. remove(target) takes O(k).

Space: O(k).

AC java:

 public class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length == 0 || k <= 0){
return new double[0];
} PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder()); int len = nums.length;
double [] res = new double[len-k+1];
for(int i = 0; i<=len; i++){
if(i>=k){
if(minHeap.size() == maxHeap.size()){
res[i-k] = ((double)minHeap.peek() + (double)maxHeap.peek())/2.0;
}else{
res[i-k] = minHeap.peek();
}
if(nums[i-k] < res[i-k]){
maxHeap.remove(nums[i-k]);
}else{
minHeap.remove(nums[i-k]);
}
}
if(i<len){
if(!maxHeap.isEmpty() && maxHeap.peek()>nums[i]){
maxHeap.offer(nums[i]);
}else{
minHeap.offer(nums[i]);
}
while(maxHeap.size() > minHeap.size()){
minHeap.offer(maxHeap.poll());
}
while(minHeap.size() - maxHeap.size() > 1){
maxHeap.offer(minHeap.poll());
}
}
}
return res;
}
}

类似Find Median from Data Stream.

LeetCode 480. Sliding Window Median的更多相关文章

  1. 480 Sliding Window Median 滑动窗口中位数

    详见:https://leetcode.com/problems/sliding-window-median/description/ C++: class Solution { public: ve ...

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

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

  3. [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 ...

  4. 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 ...

  5. Sliding Window Median LT480

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

  6. [LeetCode] 239. Sliding Window Maximum 滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  7. LeetCode题解-----Sliding Window Maximum

    题目描述: Given an array nums, there is a sliding window of size k which is moving from the very left of ...

  8. [leetcode]239. Sliding Window Maximum滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  9. 滑动窗口的中位数 · Sliding Window Median

    [抄题]: 给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数.(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字 ...

随机推荐

  1. 小数据池、is 和 ==的区别

    小数据池,在一定情况下出现内存共享(只有int  和 str 才有的)   is 和 ==的区别 id()     打印数据的地址 a  = 'hello' b = 'hello' print(a = ...

  2. php的异常和处理

    常见错误处理类型 语法错误 环境错误 逻辑错误 常见错误级别 Deprecated 最低级别的错误 不推荐,不建议,使用一些过期函数的时候会出现,程序继续执行 Notice 通知级别的错误 使用一些未 ...

  3. Yii2 自定义独立验证器

    新建一个文件: ?php /** * author : forecho <caizhenghai@gmail.com> * createTime : 2015/7/1 14:54 * de ...

  4. C++中引用编译过的C代码为什么要用“extern c”

    函数经过编译系统的翻译成汇编,函数名对应着汇编标号.  因为C编译函数名与得到的汇编代号基本一样,如:fun()=>_fun, main=>_main  但是C++中函数名与得到的汇编代号 ...

  5. $git学习总结系列(1)——基本用法

    廖雪峰的官方网站:http://www.liaoxuefeng.com/ 本文是学习廖雪峰的官方网站上git教程git基本用法的总结,详细内容可以进入廖雪峰的官方网站查看. 注:本文中的主要内容都是基 ...

  6. 关于Class.getResourceAsStream

    Properties properties = new Properties();    properties.load(new  InputStreamReader(CharactorTest.cl ...

  7. PCIE phy和控制器

    转:https://wenku.baidu.com/view/a13bc1c20722192e4436f617.html 文章中的第11页开始有划分phy和控制器部分....

  8. INSPIRED启示录 读书笔记 - 第36章 可用性与美感

    两者缺一不可 交互设计和视觉设计完全是两回事 视觉设计可以满足用户的情感需求 良好的用户体验是交互设计师和视觉设计师合作的结果.他们共同配合产品经理定义产品

  9. mysqldump 的常用操作

    以下是 mysqldump 的一些使用参数 备份数据库#mysqldump 数据库名 >数据库备份名 #mysqldump -A -u用户名 -p密码 数据库名>数据库备份名 #mysql ...

  10. Elasticsearch-->Get Started-->Basic concepts

    https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-concepts.html There ...