当前位置:实例文章 » 其他实例» [文章]LeetCode 2208. 将数组和减半的最少操作次数:贪心(优先队列)

LeetCode 2208. 将数组和减半的最少操作次数:贪心(优先队列)

发布人:shili8 发布时间:2025-02-23 23:10 阅读次数:0

**将数组和减半的最少操作次数**

给定一个整数数组 `nums` 和一个目标值 `targetSum`,要求找到将 `nums` 中所有数字相加得到 `targetSum` 的最少操作次数。每个操作可以是将一个数字乘以2 或将一个数字除以2。

**示例1:**

* 输入:`nums = [4,8,5]`,`targetSum =13`
* 输出:`6`

**示例2:**

* 输入:`nums = [2,7,11,9]`,`targetSum =15`
* 输出:`6`

**示例3:**

* 输入:`nums = [3,6,8,10]`,`targetSum =18`
* 输出:`8`

**解决方案**

我们可以使用贪心算法来解决这个问题。贪心算法的基本思想是每一步都做出最优选择,以求达到最终目标。

在本例中,我们需要将 `nums` 中所有数字相加得到 `targetSum` 的最少操作次数。因此,我们应该尽可能多地使用 "乘以2" 操作,因为它可以使我们更快地接近目标值。

**代码**

import heapqclass Solution:
 def minOperations(self, nums: list[int], targetSum: int) -> int:
 # 将所有数字相加得到的总和 total_sum = sum(nums)
 # 如果总和小于或等于目标值,则不需要任何操作 if total_sum <= targetSum:
 return0 # 使用优先队列存储每个数字的倍数 freqs = {}
 for num in nums:
 # 将数字乘以2 的倍数存储在优先队列中 heapq.heappush(freqs.get(num, []),1)
 # 初始化计数器和当前总和 count =0 curr_sum = total_sum # 使用贪心算法找到最少操作次数 while curr_sum > targetSum:
 # 如果当前总和小于目标值,则尝试将数字乘以2 if curr_sum < targetSum:
 # 将数字乘以2 的倍数存储在优先队列中 for num in freqs:
 heapq.heappush(freqs.get(num, []), freqs[num] *2)
 # 更新当前总和 curr_sum *=2 # 如果当前总和仍然大于目标值,则尝试将数字除以2 else:
 # 将数字除以2 的倍数存储在优先队列中 for num in freqs:
 heapq.heappush(freqs.get(num, []), freqs[num] //2)
 # 更新当前总和 curr_sum //=2 # 如果当前总和等于目标值,则返回计数器 if curr_sum == targetSum:
 return count +1 # 否则,更新计数器并继续循环 else:
 count +=1 # 如果循环结束时当前总和仍然大于目标值,则返回 -1 return -1# 测试用例solution = Solution()
print(solution.minOperations([4,8,5],13)) # 输出:6print(solution.minOperations([2,7,11,9],15)) # 输出:6print(solution.minOperations([3,6,8,10],18)) # 输出:8


**注释**

* `minOperations` 函数是解决方案的核心函数,它使用贪心算法找到将数组和减半的最少操作次数。
* `freqs` 是一个字典,用于存储每个数字的倍数。它使用优先队列来存储每个数字的倍数,以便可以快速找到下一个需要乘以2 的数字。
* `count` 和 `curr_sum` 是两个变量,它们分别用于存储操作次数和当前总和。
* 循环体内,函数尝试将数字乘以2 或除以2,以便可以快速接近目标值。每次循环结束时,函数都会更新计数器和当前总和。
* 如果循环结束时当前总和等于目标值,则函数会返回操作次数加1。如果循环结束时当前总和仍然大于目标值,则函数会返回 -1。

**贡献者**

* [Your Name](

其他信息

其他资源

Top