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 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: k is always smaller than input array's size for non-empty array.
class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
if(k > nums.length) {
return new double[0];
}
double[] result = new double[nums.length - k + 1];
int[] buffer = Arrays.copyOf(nums, k);
Arrays.sort(buffer);
result[0] = buffer[(k-1)/2]/2.0 + buffer[k/2]/2.0;
for(int right = k; right < nums.length; ++right) {
int pos = Arrays.binarySearch(buffer, nums[right-k]);
while(pos > 0 && buffer[pos-1] > nums[right]) {
buffer[pos] = buffer[pos-1];
--pos;
}
while(pos + 1 < k && buffer[pos+1] < nums[right]) {
buffer[pos] = buffer[pos+1];
++pos;
}
buffer[pos] = nums[right];
result[right - k + 1] = buffer[(k-1)/2]/2.0 + buffer[k/2]/2.0;
}
return result;
}
}
python:
class Solution:
def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
window = sorted(nums[0:k]) medianIndex = k
result = []
result.append(window[(k-1)//2]/2.0 + window[k//2]/2.0) for right in range(k, len(nums)):
window.remove(nums[right-k])
bisect.insort(window, nums[right])
result.append(window[(k-1)//2]/2.0 + window[k//2]/2.0) return result
Idea 2. a. Similar to find median from Data Stream LT295, besides we need to add element to the window, we need to remove element outside of window, the removing action in priority queue in java takes O(n), unless we make customized heap-based priority queue, the alternative choice is TreeSet, to deal with duplicates, use the index for equal elements.
Time complexity: O(nlogk)
Space complexity: O(k)
class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
if(k > nums.length) {
return new double[0];
}
double[] result = new double[nums.length - k + 1];
Comparator<Integer> cmp = (a, b) -> {
if(nums[a] == nums[b]) {
return a-b;
}
return Integer.compare(nums[a], nums[b]);
};
TreeSet<Integer> maxHeap = new TreeSet<>(cmp);
TreeSet<Integer> minHeap = new TreeSet<>(cmp);
for(int right = 0; right < nums.length; ++right) {
maxHeap.add(right);
minHeap.add(maxHeap.pollLast());
if(maxHeap.size() < minHeap.size()) {
maxHeap.add(minHeap.pollFirst());
}
if(right >= k-1) {
if(k%2 == 1) {
result[right-k+1] = nums[maxHeap.last()];
}
else {
result[right-k+1] = nums[maxHeap.last()]/2.0 + nums[minHeap.first()]/2.0;
}
if(!maxHeap.remove(right-k+1)) {
minHeap.remove(right-k+1);
}
}
}
return result;
}
}
Idea 2.b priority queue
Time complexity: O(nk)
Space complexity: O(k)
class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
if(k > nums.length) {
return new double[0];
}
double[] result = new double[nums.length - k + 1];
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for(int right = 0; right < nums.length; ++right) {
maxHeap.add(nums[right]);
minHeap.add(maxHeap.poll());
if(maxHeap.size() < minHeap.size()) {
maxHeap.add(minHeap.poll());
}
if(right >= k-1) {
if(k%2 == 1) {
result[right-k+1] = maxHeap.peek();
}
else {
result[right-k+1] = maxHeap.peek()/2.0 + minHeap.peek()/2.0;
}
if(!maxHeap.remove(nums[right-k+1])) {
minHeap.remove(nums[right-k+1]);
}
}
}
return result;
}
}
Idea 2.c. priority queue + hashmap to store elements outside of window, instead of remove elemnts immediately
Time complexity: O(nlogk)
Space complexity: O(n)
class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
if(k > nums.length) {
return new double[0];
}
double[] result = new double[nums.length - k + 1];
int leftCnt = 0;
int rightCnt = 0;
Map<Integer, Integer> record = new HashMap<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for(int right = 0; right < nums.length; ++right) {
maxHeap.add(nums[right]);
minHeap.add(maxHeap.poll());
if(maxHeap.size() -leftCnt < minHeap.size() - rightCnt) {
maxHeap.add(minHeap.poll());
}
if(right >= k-1) {
if(k%2 == 1) {
result[right-k+1] = maxHeap.peek();
}
else {
result[right-k+1] = maxHeap.peek()/2.0 + minHeap.peek()/2.0;
}
if(maxHeap.peek() >= nums[right-k+1]) {
if(maxHeap.peek() == nums[right-k+1]) {
maxHeap.poll();
}
else {
record.put(nums[right-k+1], record.getOrDefault(nums[right-k+1], 0) + 1);
++leftCnt;
}
}
else {
if(minHeap.peek() == nums[right-k+1]) {
minHeap.poll();
}
else {
++rightCnt;
record.put(nums[right-k+1], record.getOrDefault(nums[right-k+1], 0) + 1);
}
}
while(record.containsKey(maxHeap.peek())) {
int key = maxHeap.poll();
record.put(key, record.get(key)-1);
if(record.get(key) == 0) {
record.remove(key);
}
--leftCnt;
}
while(record.containsKey(minHeap.peek())) {
int key = minHeap.poll();
record.put(key, record.get(key)-1);
if(record.get(key) == 0) {
record.remove(key);
}
--rightCnt;
}
}
}
return result;
}
}
Sliding Window Median LT480的更多相关文章
- [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 ...
- LeetCode 480. Sliding Window Median
原题链接在这里:https://leetcode.com/problems/sliding-window-median/?tab=Description 题目: Median is the middl ...
- 【LeetCode】480. 滑动窗口中位数 Sliding Window Median(C++)
作者: 负雪明烛 id: fuxuemingzhu 公众号: 每日算法题 本文关键词:LeetCode,力扣,算法,算法题,滑动窗口,中位数,multiset,刷题群 目录 题目描述 题目大意 解题方 ...
- LintCode "Sliding Window Median" & "Data Stream Median"
Besides heap, multiset<int> can also be used: class Solution { void removeOnly1(multiset<in ...
- Lintcode360 Sliding Window Median solution 题解
[题目描述] Given an array of n integer, and a moving window(size k), move the window at each iteration f ...
- 滑动窗口的中位数 · Sliding Window Median
[抄题]: 给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数.(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字 ...
- Sliding Window Median
Description Given an array of n integer, and a moving window(size k), move the window at each iterat ...
- 480 Sliding Window Median 滑动窗口中位数
详见:https://leetcode.com/problems/sliding-window-median/description/ C++: class Solution { public: ve ...
随机推荐
- XSSExcelUtil
package com.numa.util; import org.apache.poi.hssf.usermodel.*;import org.apache.poi.hssf.util.HSSFCo ...
- Unity中的四个路径
Application.database:当前工程的Assets文件夹(编辑器) Application.StreamingAssets:IO流路径 当前工程的StreamingAssets文件夹(编 ...
- python模块 re模块与python中运用正则表达式的特点 模块知识详解
1.re模块和基础方法 2.在python中使用正则表达式的特点和问题 3.使用正则表达式的技巧 4.简单爬虫例子 一.re模块 模块引入; import re 相关知识: 1.查找: (1)find ...
- 二、Adapter 适配器
适配器:继承适配与委托适配 需求:Banner 可以输出强电流380v.弱电流12v,但是不能被直接使用.通过别的方式,介间的使用banner? 委托类图: 代码清单: 需要隐藏的功能类: publi ...
- spring jpa nativequery in与修改
参考 https://blog.csdn.net/a3025056/article/details/79022816 @Modifying@Transactional /* 如果在事务中使用需加上此注 ...
- Linux系统清除缓存
1)缓存机制介绍在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没 ...
- PTA 7-8 哈利·波特的考试(floyd)
哈利·波特要考试了,他需要你的帮助.这门课学的是用魔咒将一种动物变成另一种动物的本事.例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等.反方向变化的魔咒就是简单地将原来的魔咒倒过来念 ...
- 【Linux 系统】Linux探秘之用户态与内核态
一. Unix/Linux的体系架构 如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核).内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程 ...
- @params、@PathVariabl和@RequestParam用法与区别
[1]params params: 指定request中必须包含某些参数值是,才让该方法处理. @RequestMapping(value = "testParamsAndHeaders&q ...
- Beanstalkd消息队列的安装与使用
一.Beanstalkd是什么? Beanstalkd是一个高性能,轻量级的分布式内存队列 二.Beanstalkd特性 1.支持优先级(支持任务插队)2.延迟(实现定时任务)3.持久化(定时把内存中 ...