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.
Answers within 10^-5
of the actual value will be accepted as correct.
滑动窗口中位数。题目就是题意。这个题的思路跟295题非常像,也是需要用到优先队列。
首先创建一个长度为i - k + 1的数组记录结果,一个最大堆,一个最小堆。之后开始遍历input,按照295题的思路决定到底是把当前的数字加入最大堆还是最小堆。原则上还是保证两个堆一样大或者最大堆多一个元素。
- 如果最小堆size较大或者两者size一样,则将当前数字放入最大堆
- 如果最大堆size较大,则将当前数字放入最小堆
之后判断如果两个堆中存放的元素个数达到K了,此时就可以开始结算了。注意结算最后记得移除sliding window的第一个元素,因为window会往右移动。
时间O(nlogk)
空间O(n)
Java实现
1 class Solution { 2 public double[] medianSlidingWindow(int[] nums, int k) { 3 double[] res = new double[nums.length - k + 1]; 4 PriorityQueue<Integer> left = new PriorityQueue<>(Collections.reverseOrder()); 5 PriorityQueue<Integer> right = new PriorityQueue<>(); 6 for (int i = 0; i < nums.length; i++) { 7 if (left.size() <= right.size()) { 8 right.add(nums[i]); 9 left.add(right.remove()); 10 } else { 11 left.add(nums[i]); 12 right.add(left.remove()); 13 } 14 if (left.size() + right.size() == k) { 15 double median; 16 if (left.size() == right.size()) { 17 median = (double) ((long) left.peek() + (long) right.peek()) / 2; 18 } else { 19 median = (double) left.peek(); 20 } 21 int start = i - k + 1; 22 res[start] = median; 23 if (!left.remove(nums[start])) { 24 right.remove(nums[start]); 25 } 26 } 27 } 28 return res; 29 } 30 }
相关题目