解答一
直接使用JDK自带的优先级队列容器PriorityQueue
实现,注意需要指定排序器,默认情况下,队头为最小的对象。
package leetcode.editor.cn;
import java.util.Comparator;
import java.util.Optional;
import java.util.PriorityQueue;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int lastStoneWeight(int[] stones) {
if (stones == null) {
return 0;
}
if (stones.length == 1) {
return stones[0];
}
PriorityQueue<Integer> queue = new PriorityQueue<>(stones.length, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for (int i = 0; i < stones.length; ++i) {
queue.add(stones[i]);
}
while (queue.size() > 1) {
int x = queue.poll();
int y = queue.poll();
if (x != y) {
queue.add(x - y);
}
}
return Optional.ofNullable(queue.peek()).orElse(0);
}
}
//leetcode submit region end(Prohibit modification and deletion)
解答二
手搓一个优先级队列的实现。
package leetcode.editor.cn;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int lastStoneWeight(int[] stones) {
if (stones == null) {
return 0;
}
if (stones.length == 1) {
return stones[0];
}
int[] heap = new int[stones.length + 1];
System.arraycopy(stones, 0, heap, 1, stones.length);
// 根节点和左右孩子去比较,如果根节点的值比左右孩子的最大值小,则交换。
int nodes = heap.length / 2;
int maxLength = heap.length;
buildHeap(nodes, maxLength, heap);
while (maxLength > 1) {
int x = heap[1];
int pos = 0;
pos = maxLength - 1;
heap[1] = heap[pos];
heap[pos] = 0;
--maxLength;
buildHeap(maxLength / 2, maxLength, heap);
int y = heap[1];
if (x == y) {
pos = maxLength - 1;
heap[1] = heap[pos];
heap[pos] = 0;
--maxLength;
buildHeap(maxLength / 2, maxLength, heap);
} else {
heap[1] = x - y;
buildHeap(maxLength / 2, maxLength, heap);
}
}
return heap[1];
}
private static void buildHeap(int nodes, int maxLength, int[] heap) {
for (int i = nodes; i > 0; --i) {
int left = 2 * i;
int right = left + 1;
if (left < maxLength && right < maxLength) {
if (heap[left] > heap[right]) {
if (heap[i] < heap[left]) {
int temp = heap[i];
heap[i] = heap[left];
heap[left] = temp;
}
} else {
if (heap[i] < heap[right]) {
int temp = heap[i];
heap[i] = heap[right];
heap[right] = temp;
}
}
} else if (left < maxLength && heap[i] < heap[left]) {
int temp = heap[i];
heap[i] = heap[left];
heap[left] = temp;
}
}
}
}
//leetcode submit region end(Prohibit modification and deletion)
测试用例
package leetcode.editor.cn;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class SolutionTest {
private Solution s = null;
@Before
public void setUp() throws Exception {
s = new Solution();
}
@Test
public void test1() {
int value = s.lastStoneWeight(new int[]{2, 7, 4, 1, 8, 1});
Assert.assertTrue(String.valueOf(value), value == 1);
}
@Test
public void test2() {
int value = s.lastStoneWeight(new int[]{2, 7, 4, 1, 1});
Assert.assertTrue(String.valueOf(value), value == 1);
// 2, 7 ==>5, 4, 1, 1
// 5, 4 ==>1, 1, 1
// 1
}
@Test
public void test3() {
int value = s.lastStoneWeight(new int[]{2, 7, 4, 3, 8, 1});
Assert.assertTrue(String.valueOf(value), value == 1);
// 8, 7 ==> 2, 1, 4, 3, 1
// 4, 3 ==> 2, 1, 1, 1
// 2, 1 ==> 1, 1, 1
// 1
}
@Test
public void test4() {
int value = s.lastStoneWeight(new int[]{2, 7, 4, 3, 8, 1, 10});
Assert.assertTrue(String.valueOf(value), value == 1);
// 2, 7, 4, 3, 8, 1, 10
// 10, 8 ==> 2, 7, 4, 3, 2, 1
// 7, 4 ==> 2, 3, 3, 2, 1
// 3, 3 ==> 2, 2, 1
// 1
}
@Test
public void test5() {
int value = s.lastStoneWeight(new int[]{2, 7, 4, 3, 8, 10});
Assert.assertTrue(String.valueOf(value), value == 0);
// 2, 7, 4, 3, 8, 10
// 10, 8 ==> 2, 7, 4, 3, 2
// 7, 4 ==> 2, 3, 3, 2
// 3, 3 ==> 2, 2
// 0
}
}
参考资料