雇佣 K 位工人的总代价
难度:
标签:
题目描述
代码结果
运行时间: 107 ms, 内存: 24.9 MB
/*
* Problem: Given an array `costs`, hire `k` workers based on the following rules:
* 1. In each round, hire one worker from the first `candidates` and the last `candidates` workers.
* 2. Choose the worker with the minimum cost. If there's a tie, choose the worker with the smaller index.
* 3. Return the total cost of hiring `k` workers.
*/
import java.util.*;
import java.util.stream.IntStream;
public class SolutionStream {
public int totalCost(int[] costs, int k, int candidates) {
int totalCost = 0;
PriorityQueue<Integer> minHeap = new PriorityQueue<>((a, b) -> costs[a] == costs[b] ? a - b : costs[a] - costs[b]);
for (int i = 0; i < candidates; i++) minHeap.offer(i);
for (int i = costs.length - 1; i >= costs.length - candidates && i >= candidates; i--) minHeap.offer(i);
Set<Integer> used = new HashSet<>();
while (k > 0 && !minHeap.isEmpty()) {
int idx = minHeap.poll();
if (used.add(idx)) {
totalCost += costs[idx];
k--;
if (idx >= candidates && idx < costs.length - candidates) {
if (idx - candidates >= 0) minHeap.offer(idx - candidates);
if (idx + candidates < costs.length) minHeap.offer(idx + candidates);
}
}
}
return totalCost;
}
}
解释
方法:
该题解的思路是使用两个最小堆(left_heap和right_heap)来分别管理数组costs中的前candidates个元素和后candidates个元素。每次迭代中,从这两个堆中找出最小的元素,然后将其从堆中移除,并将其加入到总的代价中。同时,堆从costs中继续添加新的元素以保持堆的大小为candidates,直到完成k次选择。通过这种方式,可以有效地在每一轮中找到最小代价的工人并加以雇佣。
时间复杂度:
O(k log(candidates))
空间复杂度:
O(candidates)
代码细节讲解
🦆
在`totalCost`函数中,为什么选择使用两个最小堆来管理`costs`数组的前后`candidates`个元素?是否有其他数据结构可行?
▷🦆
堆的初始化和更新是如何确保每一轮都能从最前面`candidates`和最后面`candidates`人中选出代价最小的工人?
▷🦆
如何处理`costs`数组长度小于两倍`candidates`的情况,即当前后`candidates`有重叠时的特殊处理?
▷