1.题目详情
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。
2.解题思路
将石头的重量降序排列,lens记录列表长度。每一次循环,找出前两个重量大的,相减判断,如果差为0,lens减2,去掉这两个石头,下次循环从第三个元素开始,如果差不为0,相减的结果给列表的第二个元素,lens减1,并再次升序排序,下次循环从第二个元素开始。注意考虑特殊情况
3.代码实现
class Solution:
def lastStoneWeight(self, stones: List[int]) -> int:
stones.sort(reverse=True) #降序,第一个数是最大的,第二个为第二大
lens = len(stones)-1
while lens > 0:
if stones[0] - stones[1] == 0: #如果差为0,切片切掉前两个数
lens -= 2
if lens < 0: #如果只有两个数并且相等,全部粉碎
return 0
stones = stones[2:]
elif stones[0] - stones[1] != 0:
lens -= 1
stones[1] = stones[0] - stones[1]
stones = stones[1:]
stones.sort(reverse=True) #每次选最重的,新一轮排序
return stones[0]
用堆的方法
class Solution:
def lastStoneWeight(self, stones: List[int]) -> int:
heap = [-i for i in stones] #将石头重量转为负数,最小值即为原本最大值
heapq.heapify(heap) #让列表具备堆的特征
while len(heap) > 1:
x,y = heapq.heappop(heap),heapq.heappop(heap) #从堆中选出两个最小值
if x != y:
heapq.heappush(heap,x-y) #将x-y压入heap堆中
if heap:
return -heap[0] #将最小值取反
else:
return 0
4.知识点
简单了解了堆,上网查了查
以下是关于堆
一种著名的数据结构是堆(heap),它是一种优先队列。优先队列让你能够以任意顺序添加对象,并随时(可能是在两次添加对象之间)找出(并删除)最小的元素。相比于列表方法min,这样做的效率要高得多。
实际上,Python没有独立的堆类型,而只有一个包含一些堆操作函数的模块。这个模块名为heapq(其中的q表示队列),它包含6个函数,其中前4个与堆操作直接相关。必须使用列表来表示堆对象本身。
函数heappush用于在堆中添加一个元素。请注意,不能将它用于普通列表,而只能用于使用各种堆函数创建的列表。原因是元素的顺序很重要(虽然元素的排列顺序看起来有点随意,并没有严格地排序)。