返回

30天 刷题挑战:2462.雇佣K位工人的总代价全攻略

前端

2462.雇佣K位工人的总代价:分而治之算法

引言

你是一个踌躇满志的项目经理,受命为一项重要的建筑项目招募一支才华横溢的工人队伍。为了在预算内完成项目,你需要在雇佣成本和工人素质之间取得微妙的平衡。这就是 LeetCode 的 2462 号难题——雇佣 K 位工人的总代价——登场的时候了。

理解问题

问题的本质很简单:给你一个工人成本数组 costs 和一个需要雇佣的工人数量 k,你的任务是雇佣恰好 k 名工人,同时使他们的总成本最小。

算法策略:分而治之

为了解决这个问题,我们将采用一个分而治之的算法,它巧妙地将问题分解成更小的子问题,然后逐个解决它们。

具体步骤

  1. 初始化优先队列:

    • 使用两个优先队列:leftQueue 用于存储成本小于等于 costs[k] 的工人,rightQueue 用于存储成本大于 costs[k] 的工人。
  2. 填充队列:

    • 遍历 costs 数组,根据每个工人的成本将其添加到相应的队列中。
  3. 贪婪算法:

    • 循环 k 次,每次从 leftQueue(如果有)或 rightQueue 中弹出成本最低的工人,将其添加到总成本中。
  4. 计算总成本:

    • 将累积的总成本作为最终结果返回。

代码示例

    public long totalCost(int[] costs, int k) {
        // 初始化优先队列
        PriorityQueue<Integer> leftQueue = new PriorityQueue<>();
        PriorityQueue<Integer> rightQueue = new PriorityQueue<>(Collections.reverseOrder());

        // 填充队列
        for (int cost : costs) {
            if (cost <= costs[k]) {
                leftQueue.add(cost);
            } else {
                rightQueue.add(cost);
            }
        }

        // 贪婪算法
        long totalCost = 0;
        for (int i = 0; i < k; i++) {
            if (!leftQueue.isEmpty()) {
                totalCost += leftQueue.poll();
            } else {
                totalCost += rightQueue.poll();
            }
        }

        return totalCost;
    }

结论

这个分而治之的算法有效地利用了优先队列来识别成本最低的工人,从而确保在满足雇佣 k 名工人的要求的同时,最大程度地减少总成本。通过这种聪明的方法,你可以自信地承担建筑项目的重任,聘请一支才华横溢且经济高效的团队。

常见问题解答

  1. 算法的复杂度是多少?

    • 时间复杂度:O(n log n),其中 n 是 costs 数组的长度。
  2. 如何处理成本相等的工人?

    • 算法会优先雇佣成本较低的工人,但如果成本相等,则优先雇佣队列中排在前面的工人。
  3. 如果 k 超过 costs 数组的长度,会怎样?

    • 这是一种非法状态,算法会抛出异常或返回一个表示错误的结果。
  4. 这个算法可以解决哪些现实世界的问题?

    • 分配任务、资源优化、调度问题。
  5. 有哪些其他方法可以解决这个问题?

    • 暴力方法:尝试所有可能的工人组合,计算总成本并返回最小值。
    • 动态规划:使用动态规划来存储子问题的最优解。