原题链接在这里: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.

最新文章

  1. Eclipse创建Maven工程报错
  2. Python 学习第十六天 html 前端内容总结
  3. CSS-animations和transitions性能:浏览器到底做了什么?
  4. 组合模式(Composite Pattern)
  5. coreseek实战(三):全文搜索在php中应用(使用api接口)
  6. myeclipse10 .jsp将表单提交给.java(form网页与后台通信初识)
  7. A Simple Problem with Integers
  8. ListView与GridView异步加载图片
  9. c/c++面试总结(3)
  10. exists与in的使用与区别
  11. 定时工作方式2实现1s定时
  12. JS设计模式(一) 单例模式
  13. JavaEE三大框架整合
  14. (95)Wangdao.com_第二十八天_进度事件
  15. [swarthmore cs75] Compiler 3 – Cobra
  16. Java-Servlet -Helloworld
  17. 【译】第18节---数据注解-ForeignKey
  18. Capjoint
  19. background 的一些 小的细节: 1, 背景色覆盖范围: border+ width+ padding ;背景图覆盖范围: width + padding ; 2设置多个背景图片 ; 3) background-position定位百分比的计算方式: 4)background-clip 和 background-origin 的区别
  20. Linux服务器安装svn

热门文章

  1. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程
  2. UI控件之UITableView的基本属性
  3. Linux centos开机执行JAR Shell脚本
  4. JAVA 文件转字节数组转字符串
  5. Java 中的会话管理—— HttpServlet,Cookies,URL Rewriting(转)
  6. 函数---迭代器&amp;生成器&amp;列表解析&amp;三元表达式
  7. LVS 命令使用
  8. linux下查找文件或目录(which,whereis,locate,find)
  9. vm+ubuntu联网
  10. etcd 安装部署