LeetCode 1046. 最后一块石头的重量

74 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情

一、题目描述:

1046. 最后一块石头的重量 - 力扣(LeetCode) (leetcode-cn.com)

有一堆石头,每块石头的重量都是正整数。

每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

  • 如果 x == y,那么两块石头都会被完全粉碎;
  • 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。

最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。

示例:

输入:[2,7,4,1,8,1]
输出:1
解释:
先选出 78,得到 1,所以数组转换为 [2,4,1,1,1],
再选出 24,得到 2,所以数组转换为 [2,1,1,1],
接着是 21,得到 1,所以数组转换为 [1,1,1],
最后选出 11,得到 0,最终数组转换为 [1],这就是最后剩下那块石头的重量。

提示:

  • 1 <= stones.length <= 30
  • 1 <= stones[i] <= 1000

二、思路分析:

自己手写的一个大根堆

  1. 一开始push,维护一个大根堆,插入元素放在尾部,如果>父节点,就sift up
  2. 每次删除最大的元素,然后对小的元素进行 sift down
  3. 将新的元素进行插入,用push

三、AC 代码:

class Dui(object):
    def __init__(self):
        self.heap = []
        self.size = 0
    def push(self, num):
        self.size += 1
        self.heap.append(num)
        self.sift_up(self.size-1) # 对末尾元素进行上浮

    def pop(self): # 删除最大的两个元素
        self.swap(0, self.size-1)
        tmp = self.heap.pop()
        self.size -= 1
        self.sift_down(0)
        return tmp

    def sift_up(self, p):
        while p>0:
            if self.heap[(p-1)//2] < self.heap[p]:
                self.swap((p-1)//2, p)
                p = (p-1)//2
            else: break

    def sift_down(self, p):
        while 2*p + 1 < self.size:
            if 2*p+2 < self.size:
                index = self.compare(2*p+1, 2*p+2)
                if self.heap[p] < self.heap[index]:
                    self.swap(p, index)
                    p = index
                else: p = self.size
            else:
                if self.heap[p] < self.heap[2*p+1]:
                    self.swap(p, 2*p+1)
                    p = 2*p+1
                else: p = self.size

    def compare(self, p1, p2):
        if self.heap[p1] >= self.heap[p2]: return p1
        else: return p2    

    def swap(self, index1, index2):
        self.heap[index1], self.heap[index2] = self.heap[index2], self.heap[index1]

    def get_size(self):
        return self.size

class Solution(object):
    def lastStoneWeight(self, stones):
        """
        :type stones: List[int]
        :rtype: int
        """
        Heap = Dui()
        for i in stones:
            Heap.push(i)
        print(Heap.heap)
        while Heap.get_size() > 1:
            s1 = Heap.pop()
            s2 = Heap.pop()
            tmp = s1 - s2
            if tmp:
                Heap.push(tmp)
        return Heap.heap[0] if Heap.get_size()>=1 else 0