2208. 将数组和减半的最少操作次数
题目描述:给你一个正整数数组nums。每一次操作中,你可以从nums中选择任意一个数并将它减小到恰好一半。(注意,在后续操作中你可以对减半过的数继续执行操作)
请你返回将nums数组和至少减少一半的最少操作数。
解题思路:该题目解题思路很简单,也就是查找数组中最大的数值进行减半操作,直到操作之后的数组能达到原来数组和的一半。基于这个思路,我们可以使用一个最为简单思路进行解决,也就是每次筛选最大的数值,定位到当前数值的索引,然后对其减半操作,进行判断,直至达到原来数组和的一半以下。
class Solution:
def halveArray1(self, nums: list) -> int:
sumnum = sum(nums)
# 需要减少的数字
subnum = sumnum / 2
res = 0
while sumnum - sum(nums) < subnum:
maxnum = max(nums)
idx = nums.index(maxnum)
nums[idx] = nums[idx] / 2
res += 1
return res
但是该代码的时间复杂度为 $O(n^2),在该题目中就会超时,可以注意到,每次都是挑选数组中较大的数值,则可以使用优先队列进行优化代码。优化之后的代码时间复杂度就是O(n),则可以通过测试。
class Solution:
def halveArray(self, nums: list) -> int:
sumnum = sum(nums)
divnum = sumnum / 2
heap = []
for i in nums:
heapq.heappush(heap, -i)
res = 1
s = -heapq.heappop(heap) / 2
while sumnum - s > divnum:
sumnum -= s
heapq.heappush(heap, -s)
s = -heapq.heappop(heap) / 2
res += 1
return res