在问 · 算法题解

1046. 最后一块石头的重量

题目描述

输入整数数组 stones,每个元素是一块石头的重量,均为正整数。

每一轮,取出当前最重的两块石头互相撞击,设重量为 x <= y。若 x == y,两块都消失;否则重 x 的消失,另一块的重量变成 y - x 并放回。

不断重复,直到剩下的石头不足两块。返回最后剩下那块石头的重量;若一块都不剩,返回 0。

示例 1
输入:stones = [2,7,4,1,8,1]
输出:1

解释:依次撞 8 和 7、4 和 2、2 和 1、1 和 1,最后剩下一块重 1 的石头。

示例 2
输入:stones = [1]
输出:1

解释:只有一块石头,无法再撞,直接返回 1。

数据范围

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

解题思路

每回合都要“取出最大的两个”并可能“放回一个新值”,这正是大顶堆擅长的操作。Python 的 heapq 是小顶堆,所以把重量取负后入堆。弹出两次得到 y >= x,若 y > x 就把差值放回,直到堆里不足两块。

为什么正确

堆里始终是当前还存在的全部石头,堆顶是最重的一块;每回合石头数至少减少 1。

复杂度分析

时间 O(n log n),空间 O(n)。

易错点

堆可能最后为空(例如 [5,5]),直接访问 heap[0] 会越界;另外存入小顶堆时要记得取负,放回的差值也要是负数 x - y。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def lastStoneWeight(self, stones: List[int]) -> int:
        heap = [-s for s in stones]
        heapq.heapify(heap)
        while len(heap) > 1:
            y = -heapq.heappop(heap)
            x = -heapq.heappop(heap)
            if y > x:
                heapq.heappush(heap, x - y)
        return -heap[0] if heap else 0

载入编辑器,自己跑一遍 →

栈与堆 专题的其他题目

查看 栈与堆 全部题目 →