Java. Heap. Fight of the stones
\n\nclass Heap\n{\n    int [] heap;\n    int size;\n    Heap(int[] stones)\n    {\n        heap = new int[stones.length];\n        size = 0;\n        for (int i
\n```\nclass Heap\n{\n    int [] heap;\n    int size;\n    Heap(int[] stones)\n    {\n        heap = new int[stones.length];\n        size = 0;\n        for (int i = 0; i < stones.length; i++)\n            addStone(stones[i]);\n    }\n    public int removeMax() //size--\n    {\n        int answ = heap[0];\n        if (size > 0) {\n            heap[0] = heap[size - 1];\n            size--;\n        }\n        siftDown();\n        return answ;\n    }\n    public void addStone(int stone) //size++\n    {\n        size++;\n        heap[size - 1] = stone;\n        siftUp();\n    }\n\n    public int[] changePlace(int child, int[] start)\n    {\n        int tmp;\n\n        tmp = heap[child];\n        heap[child] = heap[start[0]];\n        heap[start[0]] = tmp;\n        start[0] = child;\n        return new int[]{getLeftChild(start[0]), getRightChild(start[0])};\n    }\n\n    public void siftDown()\n    {\n        int []start = new int[]{0};\n        int []leftAndRight = new int[2];\n        leftAndRight[0] = getLeftChild(start[0]);\n        leftAndRight[1] = getRightChild(start[0]);\n        int tmp;\n        while (true)\n        {\n            if (leftAndRight[0] < size && leftAndRight[1] < size)\n            {\n                if(heap[leftAndRight[0]] >= heap[leftAndRight[1]] && heap[start[0]] <= heap[leftAndRight[0]])\n                    leftAndRight = changePlace(leftAndRight[0], start);\n                else if(heap[leftAndRight[1]] > heap[leftAndRight[0]] && heap[start[0]] <= heap[leftAndRight[1]])\n                    leftAndRight = changePlace(leftAndRight[1], start);\n                else\n                    break;\n            }\n            else if (leftAndRight[0] < size && heap[start[0]] <= heap[leftAndRight[0]])\n                leftAndRight = changePlace(leftAndRight[0], start);\n            else if (leftAndRight[1] < size && heap[start[0]] <= heap[leftAndRight[1]])\n                leftAndRight = changePlace(leftAndRight[1], start);\n            else\n                break;\n        }\n    }\n\n    public void siftUp()\n    {\n        int child = size - 1;\n        int parent = getParent(child);\n        int tmp;\n        while (parent > -1 && heap[parent] < heap[child])\n        {\n            tmp = heap[child];\n            heap[child] = heap[parent];\n            heap[parent] = tmp;\n            child = parent;\n            parent = getParent(child);\n        }\n    }\n\n    public int getParent(int child)\n    {\n        return (child - 1) / 2;\n    }\n\n    public int getLeftChild(int parent)\n    {\n        return parent * 2 + 1;\n    }\n\n    public int getRightChild(int parent)\n    {\n        return parent * 2 + 2;\n    }\n}\n\nclass Solution {\n    public int lastStoneWeight(int[] stones) {\n        Heap heap = new Heap(stones);\n        int diff;\n        while (heap.size > 1)\n        {\n            diff = Math.abs(heap.removeMax() - heap.removeMax());\n            if (diff != 0)\n                heap.addStone(diff);\n        }\n        if (heap.size > 0)\n            return heap.removeMax();\n        return 0;\n    }\n}\n```
['Java']