原题链接在这里: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. Web前端开发人员和设计师必读文章推荐【系列十】

    <Web前端开发人员和设计师必读文章推荐系列十>给大家带来最近两个月发布在<梦想天空>的优秀文章,特别推荐给 Web 开发人员和设计师阅读.梦天空博客关注 前端开发 技术,展示 ...

  2. windows通过ftp下载linux文件

    # windows 下载 linux的文件>> ftp <domain_or_ip>>> <input_username>>> <in ...

  3. uboot相关的几篇好文

    http://www.eeworld.com.cn/mcu/2015/0727/article_21246.html http://blog.csdn.net/kernel_yx/article/de ...

  4. java基础之bit、byte、char、String

    bit 位,二进制数据0或1 byte 字节,一个字节等于8位二进制数 char 字符, String 字符串,一串字符 常见转换 1 字母  = 1byte = 8 bit 1 汉字  = 2byt ...

  5. Go 字符串相关-标准库

    标准库中有四个包对字符串处理尤为重要: bytes strings strconv unicode strings包提供了许多如字符串的查询.替换.比较.截断.拆分和合并等功能. bytes包也提供了 ...

  6. freopen重定向输入

    #include <bits\stdc++.h> using namespace std; int main() { freopen("C:\\Users\\dcf\\Deskt ...

  7. juniper防火墙清空配置恢复出厂设置命令

    1. console进入防火墙之后,输入unset all ,然后选择 yes2. 然后输入 reset ,回车,选择 no ,再选择 yes .然后等待防火墙重启. 恢复出厂默认配置: 1.在Con ...

  8. 30道linux运维面试题(很精典)

    https://zhangge.net/1986.html 1.linux 如何挂在 windows 下的共享目录         Shell   1 mount.cifs //192.168.1.3 ...

  9. /var/spool/clientmqueue 爆满问题

    当你使用简单的sendmail发邮件的时候,或者系统默认要发一些邮件(比如cron发的邮件)的时候,首先会把邮件拷贝到这个目录里,然后等待MTA(mail transfer agent) 来处理,MT ...

  10. Proxy动态代理

    Proxy动态代理 package com.test.dynamicproxy; public interface Subject { public void request(); } package ...