Java clean code with MinMaxHeap implementation.
O(logN) for addElement\nO(1) for calculateMKAverage\n\nclass MKAverage {\n    int m , k;\n    LinkedList<Integer> q = new LinkedList<>();\n    MinMaxQ head = ne
O(logN) for addElement\nO(1) for calculateMKAverage\n```\nclass MKAverage {\n    int m , k;\n    LinkedList<Integer> q = new LinkedList<>();\n    MinMaxQ head = new MinMaxQ();\n    MinMaxQ body = new MinMaxQ();\n    MinMaxQ tail = new MinMaxQ();\n    \n    public MKAverage(int m, int k) {\n        this.m=m;\n        this.k=k;\n    }\n    \n    public void addElement(int num) {\n        if (q.size()==m) {\n            int pre = q.poll();\n            if (tail.contains(pre)) {\n                tail.remove(pre);\n            } else if (body.contains(pre)) {\n                body.remove(pre);\n                body.add(tail.pollMin());\n            } else if (head.contains(pre)){\n                head.remove(pre);\n                body.add(tail.pollMin());\n                head.add(body.pollMin());\n            }\n        }\n        \n        head.add(num);\n        if (head.count>k) {\n            body.add(head.pollMax());\n            if (body.count>(m-2*k)) \n                tail.add(body.pollMax());\n        }\n        q.offer(num);\n    }\n    \n    public int calculateMKAverage() {\n        if (q.size()<m) return -1; \n        return (int)Math.floor(body.sum/(m-2*k));\n    }\n    \n    class MinMaxQ {\n        int count = 0;\n        long sum = 0;\n        TreeMap<Integer, Integer> map = new TreeMap<>();\n        Integer min() { return map.firstKey();}\n        Integer max() { return map.lastKey();}\n        int count() { return count;}\n        long sum() { return sum;}\n        boolean contains(int num) { return map.containsKey(num);}\n        boolean isEmpty(){ return map.isEmpty();}\n        \n        int add(int num) {\n            map.merge(num, 1, (a,b)->a+b);\n            sum+=num;\n            return ++count;\n        }\n        \n        Integer pollMin() {\n            Integer min = this.min();\n            if (min!=null) remove(min);\n            return min;\n        }\n        \n        Integer pollMax() {\n            Integer max = this.max();\n            if (max!=null) remove(max);\n            return max;\n        }\n        \n        boolean remove(int num) {\n            if (!map.containsKey(num)) return false;\n            map.merge(num, -1, (a,b)->a+b);\n            if (map.get(num)==0) \n                map.remove(num);\n            count--;\n            sum-=num;\n            return true;\n        }\n    }\n}\n```
[]