|
| 1 | +package com.diguage.algo.leetcode; |
| 2 | + |
| 3 | +import java.util.PriorityQueue; |
| 4 | +import java.util.Queue; |
| 5 | + |
| 6 | +public class _0480_SlidingWindowMedian { |
| 7 | + // tag::answer[] |
| 8 | + |
| 9 | + /** |
| 10 | + * 答案是正确的,超大数组测试时,超时了。 |
| 11 | + * |
| 12 | + * @author D瓜哥 · https://www.diguage.com |
| 13 | + * @since 2024-08-30 11:45:50 |
| 14 | + */ |
| 15 | + public double[] medianSlidingWindow(int[] nums, int k) { |
| 16 | + // 如果窗口是奇数,则 topSmall 多一个 |
| 17 | + Queue<Integer> topSmall = new PriorityQueue<>((a, b) -> Integer.compare(a, b)); |
| 18 | + // 使用 Integer.compare,防止两个最小负数相减时溢出 |
| 19 | + Queue<Integer> topLarge = new PriorityQueue<>((a, b) -> Integer.compare(b, a)); |
| 20 | + double[] result = new double[nums.length - k + 1]; |
| 21 | + for (int i = 0; i < k; i++) { |
| 22 | + topSmall.add(nums[i]); |
| 23 | + } |
| 24 | + for (int i = 0; i < k / 2; i++) { |
| 25 | + topLarge.add(topSmall.poll()); |
| 26 | + } |
| 27 | + // 先相处再相加,防止溢出 |
| 28 | + result[0] = k % 2 == 1 ? 1.0 * topSmall.peek() |
| 29 | + : topSmall.peek() / 2.0 + topLarge.peek() / 2.0; |
| 30 | + for (int i = k; i < nums.length; i++) { |
| 31 | + int num = nums[i]; |
| 32 | + if (topSmall.peek() <= num) { |
| 33 | + topSmall.add(num); |
| 34 | + } else { |
| 35 | + topLarge.add(num); |
| 36 | + } |
| 37 | + |
| 38 | + int delNum = nums[i - k]; |
| 39 | + if (topSmall.peek() <= delNum) { |
| 40 | + topSmall.remove(delNum); |
| 41 | + } else { |
| 42 | + topLarge.remove(delNum); |
| 43 | + } |
| 44 | + // 添加,删除,再平衡双堆,这样才能保证堆的平衡性 |
| 45 | + // topSmall 应该始终大于等于 topLarge |
| 46 | + while (topLarge.size() > topSmall.size()) { |
| 47 | + topSmall.add(topLarge.poll()); |
| 48 | + } |
| 49 | + // topSmall 与 topLarge 的差值不能大于 1 |
| 50 | + while (topSmall.size() - topLarge.size() > 1) { |
| 51 | + topLarge.add(topSmall.poll()); |
| 52 | + } |
| 53 | + |
| 54 | + result[i - k + 1] = k % 2 == 1 ? 1.0 * topSmall.peek() |
| 55 | + : topSmall.peek() / 2.0 + topLarge.peek() / 2.0; |
| 56 | + } |
| 57 | + return result; |
| 58 | + } |
| 59 | + // end::answer[] |
| 60 | +} |
0 commit comments