Leetcode 480.滑动窗口中位数
滑动窗口中位数
中位数是有序序列最中间的那个数。如果序列的大小是偶数,则没有最中间的数;此时中位数是最中间的两个数的平均数。
例如:
[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.滑动窗口中位数的更多相关文章
- Java实现 LeetCode 480 滑动窗口中位数
480. 滑动窗口中位数 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 ...
- LeetCode295-Find Median from Data Stream && 480. 滑动窗口中位数
中位数是有序列表中间的数.如果列表长度是偶数,中位数则是中间两个数的平均值. 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一个支持以下两种操 ...
- 【LeetCode】480. 滑动窗口中位数 Sliding Window Median(C++)
作者: 负雪明烛 id: fuxuemingzhu 公众号: 每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,中位数,multiset,刷题群 目录 题目描述 题目大意 解题方 ...
- 【Leetcode 二分】 滑动窗口中位数(480)
题目 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) / 2 ...
- [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 239. 滑动窗口最大值】解题报告
思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...
- Leetcode 239.滑动窗口最大值
滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...
- leetcode 239. 滑动窗口最大值(python)
1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...
- leetcode全部滑动窗口题目总结C++写法(完结)
3. 无重复字符的最长子串 A: 要找最长的无重复子串,所以用一个map保存出现过的字符,并且维持一个窗口,用le和ri指针标识.ri为当前要遍历的字符,如果ri字符在map中出现过,那么将le字符从 ...
随机推荐
- 织梦DeDeCMS友情链接文字显示不全
文件:/include/taglib/flink.lib.php 把下面代码中的24改为合适的值 $attlist=”type|textall,row|24,titlelen|24,linktype| ...
- VC++堆栈大小设置
VC++堆栈默认大小是1M,如果你分配大于1M的堆,一般会出异常,这里你要把堆调大些,下面是VC++6.0与VC++2010的设置方法 VC++6.0: 工程==>设置==>“连接”界面, ...
- ZOJ 3471 Most Powerful (状压DP,经典)
题意: 有n个原子,每当两个原子碰撞时就会产生能量,并且消耗其中一个原子.已知每两个原子碰撞时消耗其中指定一个原子所产生的能量,问最多能产生多少能量? 思路: 一开始以为是找一个有序序列,使得能量最大 ...
- python基础教程总结6——类
1. 如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class ...
- Linux 的数字权限意义
三个组 每个都有三个权限 r w x每个权限用二进制 0 和 1 标示 1即为有此权限 0 标示无权限 ower group other r w x r w x r w x 每个组 ...
- MovieReview—Wile Hunter(荒野猎人)
Faith is Power Faith is power, this sentence is not wrong. Find your own beliefs, and strug ...
- Oracle 11g 新特性 – HM(Hang Manager)简介
在这篇文章中我们会对oracle 11g 新特性—hang 管理器(Hang Manager) 进行介绍.我们需要说明,HM 只在RAC 数据库中存在. 在我们诊断数据库问题的时候,经常会遇到一些数据 ...
- UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)
大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...
- UVA 1616 Caravan Robbers 商队抢劫者(二分)
x越大越难满足条件,二分,每次贪心的选区间判断是否合法.此题精度要求很高需要用long double,结果要输出分数,那么就枚举一下分母,然后求出分子,在判断一下和原来的数的误差. #include& ...
- VC++:鼠标的使用
长期改变鼠标形状: SetClassLongPtr(GetSafeHwnd(), GCLP_HCURSOR, (LONG)LoadCursor(NULL, IDC_WAIT));//这个是x64下可以 ...