heapq
模組是一個最小堆(Min-Heap),因此需要將所有石頭的重量取負值來模擬最大堆(Max-Heap)。heapq
模組默認是最小堆,而題目需要的是最大堆。取負後可以在取出元素時先轉換回正數,模擬最大堆的行為。heapq.heapify()
將負值石頭列表轉換成堆結構。import heapq
def lastStoneWeight(stones):
# 1. 將石頭重量取負數,轉換為最大堆
stones = [-stone for stone in stones]
heapq.heapify(stones)
# 2. 重複撞擊石頭直到剩下最多一塊
while len(stones) > 1:
# 取出兩塊最重的石頭
stone1 = -heapq.heappop(stones)
stone2 = -heapq.heappop(stones)
# 如果兩塊石頭不相等,將剩下的重量放回堆中
if stone1 != stone2:
heapq.heappush(stones, -(stone1 - stone2))
# 3. 返回最終剩餘的石頭重量(若無剩餘則返回0)
return -stones[0] if stones else 0
時間複雜度:
O(N log N)
:最初建立堆的操作是 O(N)
,每次取出最大值並重新插入的操作是 O(log N)
。在最壞情況下,可能需要進行 N
次操作,因此最終時間複雜度為 O(N log N)
。O(N)
:需要用到一個堆結構來存放石頭,因此空間複雜度為 O(N)
。本題可以視作「模擬撞擊過程並持續保持最大值」的問題,因此也可以用其他方式如排序、暴力解法來實現,但時間複雜度和效率都不如使用堆結構。