zoukankan      html  css  js  c++  java
  • [LeetCode] 480. Sliding Window Median

    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 }

    相关题目

    295. Find Median from Data Stream

    480. Sliding Window Median

    LeetCode 题目总结

  • 相关阅读:
    Java中的subList方法
    某同学工作之后的感悟
    存放80000000学生成绩的集合,怎么统计平均分性能高
    为了金秋那沉甸甸的麦穗,我绝不辜负春天
    subList?? subString???
    "爸妈没多大本事"……
    中秋节支付宝口令红包解析
    算法>动态规划(一) 小强斋
    数据结构>优先队列(堆) 小强斋
    算法>贪心算法 小强斋
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13063517.html
Copyright © 2011-2022 走看看