static void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
static void siftDown(int *h, int n, int i) {
for (;;) {
int max = i, l = 2 * i + 1, r = 2 * i + 2;
if (l < n && h[l] > h[max])
max = l;
if (r < n && h[r] > h[max])
max = r;
if (max == i)
return;
swap(&h[max], &h[i]);
i = max;
}
}
static void siftUp(int *h, int i) {
while (i > 0 && h[(i - 1) / 2] < h[i]) {
swap(&h[(i - 1) / 2], &h[i]);
i = (i - 1) / 2;
}
}
static int pop(int *h, int *n) {
int top = h[0];
h[0] = h[--*n];
siftDown(h, *n, 0);
return top;
}
// uses stones itself as a max-heap
int lastStoneWeight(int *stones, int stonesSize) {
int n = stonesSize;
for (int i = n / 2 - 1; i >= 0; i--)
siftDown(stones, n, i);
while (n > 1) {
int y = pop(stones, &n);
int x = pop(stones, &n);
if (y != x) {
stones[n] = y - x;
siftUp(stones, n++);
}
}
return n == 0 ? 0 : stones[0];
}
#include <queue>
#include <vector>
using namespace std;
class Solution {
public:
int lastStoneWeight(vector<int> &stones) {
priority_queue<int> pq(stones.begin(), stones.end());
while (pq.size() > 1) {
int y = pq.top();
pq.pop();
int x = pq.top();
pq.pop();
if (y != x)
pq.push(y - x);
}
return pq.empty() ? 0 : pq.top();
}
};
package heaps
import (
"container/heap"
"sort"
)
type maxHeap struct{ sort.IntSlice }
func (h maxHeap) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
func (h *maxHeap) Push(x any) { h.IntSlice = append(h.IntSlice, x.(int)) }
func (h *maxHeap) Pop() any {
old := h.IntSlice
x := old[len(old)-1]
h.IntSlice = old[:len(old)-1]
return x
}
func lastStoneWeight(stones []int) int {
pq := &maxHeap{stones}
heap.Init(pq)
for pq.Len() > 1 {
y := heap.Pop(pq).(int)
x := heap.Pop(pq).(int)
if y != x {
heap.Push(pq, y-x)
}
}
if pq.Len() == 0 {
return 0
}
return pq.IntSlice[0]
}
import java.util.Collections;
import java.util.PriorityQueue;
class Solution {
public int lastStoneWeight(int[] stones) {
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
for (int s : stones)
pq.offer(s);
while (pq.size() > 1) {
int y = pq.poll();
int x = pq.poll();
if (y != x)
pq.offer(y - x);
}
return pq.isEmpty() ? 0 : pq.peek();
}
}
class MaxHeap {
constructor() {
this.data = [];
}
size() {
return this.data.length;
}
top() {
return this.data[0];
}
push(val) {
const h = this.data;
h.push(val);
let i = h.length - 1;
while (i > 0) {
const p = (i - 1) >> 1;
if (h[p] >= h[i]) break;
[h[p], h[i]] = [h[i], h[p]];
i = p;
}
}
pop() {
const h = this.data;
const top = h[0];
const last = h.pop();
if (h.length === 0) return top;
h[0] = last;
let i = 0;
for (;;) {
let max = i;
const l = 2 * i + 1,
r = 2 * i + 2;
if (l < h.length && h[l] > h[max]) max = l;
if (r < h.length && h[r] > h[max]) max = r;
if (max === i) return top;
[h[max], h[i]] = [h[i], h[max]];
i = max;
}
}
}
/**
* @param {number[]} stones
* @return {number}
*/
var lastStoneWeight = function (stones) {
const pq = new MaxHeap();
for (const s of stones) pq.push(s);
while (pq.size() > 1) {
const y = pq.pop();
const x = pq.pop();
if (y !== x) pq.push(y - x);
}
return pq.size() === 0 ? 0 : pq.top();
};
import heapq
from typing import List
class Solution:
def lastStoneWeight(self, stones: List[int]) -> int:
pq = [-s for s in stones] # negate for a max-heap
heapq.heapify(pq)
while len(pq) > 1:
y = -heapq.heappop(pq)
x = -heapq.heappop(pq)
if y != x:
heapq.heappush(pq, -(y - x))
return -pq[0] if pq else 0
use std::collections::BinaryHeap;
impl Solution {
pub fn last_stone_weight(stones: Vec<i32>) -> i32 {
let mut pq = BinaryHeap::from(stones);
while pq.len() > 1 {
let y = pq.pop().unwrap();
let x = pq.pop().unwrap();
if y != x {
pq.push(y - x);
}
}
pq.pop().unwrap_or(0)
}
}