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 ...
随机推荐
- Jetty 与 Tomcat 的比较
Tomcat 和 Jetty 都是作为一个 Servlet 引擎应用的比较广泛,可以将它们比作为中国与美国的关系,虽然 Jetty 正常成长为一个优秀的 Servlet 引擎,但是目前的 Tomcat ...
- Push API
[Push API] The Push API gives web applications the ability to receive messages pushed to them from a ...
- json转换工具类:json<===>list或者对象
public class JsonTools { /** * POJO 转 JSON */ public static String createJsonString(Object object) { ...
- python网络编程之C/S架构介绍
标签(空格分隔): c/s架构介绍 什么是C/S架构 C指的是client(客户端软件),S指的是Server(服务端软件),后续我们可以试着写个c/s软件实现服务器软件与客户端软件基于网络通信: 计 ...
- day32 并发编程
并发编程 并发编程的理论 python中实现多进程 进程测试 import os import time while True: time.sleep(0.5) print("hahaha& ...
- 纯css3棋盘图案背景以及45度斜纹背景
css代码 .stripes { height: 250px; width: 375px; float: left; margin: 10px; ...
- rancher 2 webhook 格式
{ "version":"4", "groupKey":<string>, "status":"& ...
- 二叉树的深度优先遍历与广度优先遍历 [ C++ 实现 ]
深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点 ...
- 开机进入boot menu和application menu,无法开机
1.开机点击F1进入到bios界面 2.进入Security—Secure Boot—Disabled 如果不修改Secure boot选项为Disabled,在光驱引导时可能会出现报错 3. ...
- 用Python监听鼠标和键盘事件
PyHook是一个基于Python的“钩子”库,主要用于监听当前电脑上鼠标和键盘的事件.这个库依赖于另一个Python库PyWin32,如同名字所显示的,PyWin32只能运行在Windows平台,所 ...