import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.PriorityQueue;

/**
 * @author liweiwei1419
 * @date 2019/10/11 8:50 下午
 */
public class Solution {
    public double[] medianSlidingWindow(int[] nums, int k) {
        int len = nums.length;
        int windowLen = len - k + 1;
        double[] res = new double[windowLen];
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        // 下一个要填的值
        int next = 0;
        // 循环不变量:
        // 1、maxHeap 的堆顶小于等于 minHeap 的堆顶
        // 2、maxHeap.size() = minHeap.size() 或者
        // 3、maxHeap.size() = minHeap.size() + 1,这样中位数就在 maxHeap 的堆顶
        for (int i = 0; i < len; i++) {
            // 步骤 1:加入元素的时候,保持第 1、2、3 点
            maxHeap.add(nums[i]);
            minHeap.add(maxHeap.poll());
            if ((i & 1) == 0) {
                // 这个语义太难理解:
                // 如果还未添加 nums[i] 之前是偶数,那么添加 nums[i] 的效果是 maxHeap 多 1 个元素
                maxHeap.add(minHeap.poll());
            }
            // 步骤 2:移除窗口外的值,移除滑动窗口的左边界
            // 假设修正法:默认是大顶堆移除了一个元素
            if (i >= k) {
                int removeFrom = 1;
                // 如果不是在最小堆,就在最大堆
                if (minHeap.contains(nums[i - k])) {
                    minHeap.remove(nums[i - k]);
                    removeFrom = 0;
                } else {
                    maxHeap.remove(nums[i - k]);
                }
                // 步骤 3:保持第 2、3 点
                if ((i & 1) == 1 && removeFrom == 1) {
                    maxHeap.add(minHeap.poll());
                }
                if ((i & 1) == 0 && removeFrom == 0) {
                    minHeap.add(maxHeap.poll());
                }
            }
            // 步骤 4:求滑动窗口的中位数
            if (i >= k - 1) {
                if (maxHeap.size() > minHeap.size()) {
                    res[next] = maxHeap.peek();
                } else {
                    res[next] = minHeap.peek() / 2.0 + maxHeap.peek() / 2.0;
                }
                next++;
            }
        }
        return res;
    }


    public static void main(String[] args) {
        int a = 2147483647;
        System.out.println(Integer.MAX_VALUE);
        // int[] nums = {1,3,-1,-3,5,3,6,7};
        int[] nums = {Integer.MAX_VALUE, Integer.MAX_VALUE};
        int k = 2;
        Solution solution = new Solution();
        double[] res = solution.medianSlidingWindow(nums, k);
        System.out.println(Arrays.toString(res));
    }
}