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字符从 ...
随机推荐
- <Android 应用 之路> 天气预报(二)
界面组成 载入界面 显示界面 Activity两个,一个用来显示载入界面,一个用来显示天气信息 主要代码如下: public class MyActivity extends Activity { p ...
- Ubuntu批量修改权限
Ubuntu中有两个修改命令可以用到,「change mode」&「change owner」 即chmod以及chown,其中可以用递归参数-R来实现更改所有子文件和子目录的权限. 1.利用 ...
- android dialog style属性设置
<!--最近做项目,用到alertDialog,用系统自带的style很难看,所以查了资料自己定义了个style. res/value/style.xml内增加以下代码:--> <s ...
- ABAP和Java的单元测试Unit Test
ABAP ABAP class单元测试的执行入口,CLASS_SETUP, 是硬编码在单元测试框架实现CL_AUNIT_TEST_CLASS里的. 待执行的单元测试方法通过CL_AUNIT_TEST_ ...
- AJAX不能访问MVC后台程序的问题
AJAX不能访问后台的MVC有可能是MVC的后台程序加入了身份验证[Authorize]标记,这样前台的AJAX虽然结果显示的是4和200但是responsetext的值可以看到是返回了一个配置文件中 ...
- UVA12897 - Decoding Baby Boos
没必要每次都真的修改一遍字母值,用一个标记表示字母最后的值,最后一遍的时候再进行修改 #include<cstdio> #include<cstring> +; char st ...
- ArcGis server发布地图服务
ArcGIS server发布服务: 首先修改地图文档属性中的关联默认数据库 最后使用分享将地图服务发布到server上,是地图服务可以使用: 注意一定要勾选 Feature Access选项 fea ...
- python_103_属性方法例子
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): pr ...
- vscode的eslint插件不起作用
最近在用vue进行开发,但是vsCode中的eslint插件装上之后不起作用 1.vsCode打开“设置”,选择"settings.json" 2.输入一段脚本 "esl ...
- Leetcode 20 有效的括号valid-parentheses(栈)
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 注意空字符串可被认 ...