刷无穷 1383 ~ 团队表现最大化
基本信息
- 题号:1383
- 题厂:脸书
- 难度系数:难
一个团队有 n 个码工,每个码工有对应的效率和速度。问从中选「最多」k 个码工,怎么实现工作表现最大化???!!!
例如 n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 2,返回 60. 选择码工 (10,4)和(5,7)可达效率最高,performance = (10 + 5) * min(4, 7) = 60
解题思路
- 遇上此题就不要死磕「效率」「速度」「表现」三者之间的关系到底是怎么回事了,想办法让 performance 达到最大值极了
- 根据数学计算公式,就是如何让「速度和」和「最小效率」取到最大值。于是「贪心算法」登场了。
- 答案得知,最小效率值为 4,意味着如果码工的效率大于 4 是不可能参加计数的,于是想到用 maxHeap;
- 至于累积速度,只能在效率大于或等于 4 的码工当中选择。如果最多要选 k 个码工,那可以准备一个长度为 k 的 minHeap,累积速度 minHeap 存放 top k 速度……
class Solution:
def maxPerformance(self, n: int, speed: List[int], efficiency: List[int], k: int) -> int:
# 初始化 maxHeap,配对为「-efficiency ~ speed」
maxHeap = []
heapq.heapify(maxHeap)
for i in range(n):
maxHeap.append([-efficiency[i], speed[i]])
# 初始化存放 top k 速度的 minHeap
availableSpeed = []
heapq.heapify(availableSpeed)
accSpeed = 0
res = 0
# 遍历已配对的 maxHeap
# availableSpeed 长度小于 k 时,直接往里面添加速度
# availableSpeed 长度大于等于 k 时,看是否需要让最小值和当前速度替换
while maxHeap:
eff, speed = heapq.heappop(maxHeap)
if len(availableSpeed) < k:
accSpeed += speed
heapq.heappush(availableSpeed, speed)
elif availableSpeed[0] < speed:
accSpeed -= heapq.heappop(availableSpeed)
accSpeed += speed
heapq.heappush(availableSpeed, speed)
res = max(res, -eff * accSpeed)
return res % (10**9+7)
Constraints
1 <= k <= n <= 105speed.length == nefficiency.length == n1 <= speed[i] <= 1051 <= efficiency[i] <= 108
Big O
- Time:O( nlogn ),遍历了长度为 n 的 maxHeap,遍历过程中用到了 heappop 和 heappush,复杂度为 logn
- Space:O(n + k),创建了长度为 n 的maxHeap 和长度为 k 的 availableSpeed
测试
- 当 k = 1 时;
- ……
总结
- 绕来绕去想了 2 天才想出来😭
- 突破口为思考用「贪心」思路获得最大值,再根据贪心思路初始化相应 maxHeap 和 minHeap 帮忙解题
- 鉴于贪心和 heap 都属于中难档算法 + 数据结构,然后还要二者结合,此题非难挡莫属😭
- 考场上遇到,赶脚很难在 30 分钟内有思路😭