LeetCode 480. Sliding Window Median
原题链接在这里: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的更多相关文章
- 480 Sliding Window Median 滑动窗口中位数
详见:https://leetcode.com/problems/sliding-window-median/description/ C++: class Solution { public: ve ...
- 【LeetCode】480. 滑动窗口中位数 Sliding Window Median(C++)
作者: 负雪明烛 id: fuxuemingzhu 公众号: 每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,中位数,multiset,刷题群 目录 题目描述 题目大意 解题方 ...
- [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 ...
- 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 ...
- 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 ...
- [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 ...
- LeetCode题解-----Sliding Window Maximum
题目描述: Given an array nums, there is a sliding window of size k which is moving from the very left of ...
- [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 ...
- 滑动窗口的中位数 · Sliding Window Median
[抄题]: 给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数.(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字 ...
随机推荐
- OpenGL学习进程(4)第二课:绘制图形
本节是OpenGL学习的第二个课时,下面介绍如何用点和线来绘制图形: (1)用点的坐标来绘制矩形: #include <GL/glut.h> void display(void) ...
- HTTP学习笔记02-HTTP报文格式之概述
HTTP学习笔记02-HTTP报文格式之概述 HTTP学习笔记02-HTTP报文格式之概述 HTTP报文格式 报文的语法 起始行 首部 实体部分 学习一个协议感觉最有意思的就是看包结构…在我看来这是唯 ...
- linux 网卡buffer大小
参考截取一部分:https://blog.csdn.net/ysu108/article/details/7764461 在linux下可以修改协议栈改变tcp缓冲相关参数: 修改系统套接字缓冲区 e ...
- HNOI2019梦游记
\(Day_0\) 十点半开始睡觉,开始了八个小时的不眠之夜,整晚都没睡着,这状态明天肯定挂了 \(Day_1\) 开局一条鱼,计算几何只会\(20\) 还是\(T2\)的\(20\)纯暴力好打,\( ...
- Java中系统时间的获取_currentTimeMillis()函数应用解读
快速解读 System.currentTimeMillis()+time*1000) 的含义 一.时间的单位转换 1秒=1000毫秒(ms) 1毫秒=1/1,000秒(s)1秒=1,000,000 微 ...
- tree 命令【转】
本文转载自:http://www.jb51.net/LINUXjishu/283874.html linux下怎么用tree命令以树形结构显示文件目录结构?tree命令可以以树形结构显示文件目录结构, ...
- Python 列表List的定义及操作
# 列表概念:有序的可变的元素集合 # 定义 # 直接定义 nums = [1,2,3,4,5] # 通过range函数构造,python2 和python3 版本之间的差异: # python3 用 ...
- HDFS数据流-剖析文件读取及写入
HDFS数据流-剖析文件读取及写入 文件读取 1. 客户端通过调用FileSystem对象的open方法来打开希望读取的文件,对于HDFS来说,这个对象是分布式文件系统的一个实例.2. Distrib ...
- [转]Android:改变Activity切换方式
overridePendingTransition(enterAnim, exitAnim); Intent intent =new Intent(this,item2.class); startAc ...
- myEclipse 输入时英文自动变成2个字符大小
比如这样: ——这是输入法的问题,输入法被误设为圆角了. 输入法有区分圆角半角,正常来说我们使用的都是半角. 那么如何切换半圆角? ——比如:百度输入法 首先,将半圆角的快捷键显示出来: ——点击“d ...