1. 程式人生 > >Google面試題專題10 - leetcode857. Minimum Cost to Hire K Workers

Google面試題專題10 - leetcode857. Minimum Cost to Hire K Workers

857. Minimum Cost to Hire K Workers - Hard

題目描述

有 N 名工人。第 i 名工人的工作質量為 quality[i],期望的最低工資為 wage[i]。
現在我們想僱傭 K 名工人組成一個工資組,且必須按照以下規則向他們支付工資:
1)對工資組中的每名工人,應當按其工作質量與同組其他工人的工作質量的比值來支付工資;
2)工資組中的每名工人至少應當得到他們的最低期望工資。
返回組成一個滿足上述條件的工資組所需的最少金額。

例子
Example 1:

Input: quality = [10,20,5], wage = [70,50,30], K = 2
Output: 105.00000

Explanation: We pay 70 to 0-th worker and 35 to 2-th worker.

Example 2:

Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
Output: 30.66667

Explanation: We pay 4 to 0-th worker, 13.33333 to 2-th and 3-th workers seperately.

思想
規則1:應當按其工作質量與同組其他工人的工作質量的比值來支付工資;

表明:工資組內的每名工人最終應具有相同的ratio

= wage[i]/quality[i]

1)記工人i 的ratio[i] = wage[i]/quality[i],並按ratio升序排列
2)若選擇ratio[i]作為base-ratio,則只有工人j(j<=i)滿足規則2(即:支付給工人j的工資為ratio[i] * quality[j],要 滿足>wage[j])
ratio[j]<=ratio[i] ==>wage[j] = ratio[j] * quality[j] <= ratio[i] * quality[j]
3)遍歷所有可能的ratio[i],並在[0,i]中選擇wage最少的K名工人

所需的總工資 = base-ratio * 總質量;
用堆來維護K個工人的quality。因為ratio固定,所以quality越低則所需wage越少。

解法
複雜度:時間O(nlogn),空間O(n)。

import heapq
class Solution(object):
    def mincostToHireWorkers(self, quality, wage, K):
        """
        :type quality: List[int]
        :type wage: List[int]
        :type K: int
        :rtype: float
        """
        workers = sorted([(float(w)/q, q) for w, q in zip(wage, quality)])
        res = float('inf')
        qSum = 0
        heap = []
        for r, q in workers:
            heapq.heappush(heap, -q)
            qSum += q
            if len(heap) == K:
                res = min(res, qSum * r)
                qSum += heapq.heappop(heap)    # 彈出工資最大的
        return res