[LeetCode] 1383. Maximum Performance of a Team
You are given two integers n
and k
and two integer arrays speed
and efficiency
both of length n
. There are n
engineers numbered from 1
to n
. speed[i]
and efficiency[i]
represent the speed and efficiency of the ith
engineer respectively.
Choose at most k
different engineers out of the n
engineers to form a team with the maximum performance.
The performance of a team is the sum of its engineers' speeds multiplied by the minimum efficiency among its engineers.
Return the maximum performance of this team. Since the answer can be a huge number, return it modulo 109 + 7
.
Example 1:
Input: n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 2 Output: 60 Explanation: We have the maximum performance of the team by selecting engineer 2 (with speed=10 and efficiency=4) and engineer 5 (with speed=5 and efficiency=7). That is, performance = (10 + 5) * min(4, 7) = 60.
Example 2:
Input: n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 3 Output: 68 Explanation: This is the same example as the first but k = 3. We can select engineer 1, engineer 2 and engineer 5 to get the maximum performance of the team. That is, performance = (2 + 10 + 5) * min(5, 4, 7) = 68.
Example 3:
Input: n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 4 Output: 72
Constraints:
1 <= k <= n <= 105
speed.length == n
efficiency.length == n
1 <= speed[i] <= 105
1 <= efficiency[i] <= 108
最大的团队表现值。
给定两个整数
n
和k
,以及两个长度为n
的整数数组speed
和efficiency
。现有n
名工程师,编号从1
到n
。其中speed[i]
和efficiency[i]
分别代表第i
位工程师的速度和效率。从这
n
名工程师中最多选择k
名不同的工程师,使其组成的团队具有最大的团队表现值。团队表现值 的定义为:一个团队中「所有工程师速度的和」乘以他们「效率值中的最小值」。
请你返回该团队的最大团队表现值,由于答案可能很大,请你返回结果对
10^9 + 7
取余后的结果。
思路是贪心,具体做法设计排序 + 最小堆。
注意题目对团队表现值的定义,表现值 = sum(speed of k engineers) * min(efficiency)。为了使最后的表现值更大,这里我们需要从 n 名工程师里挑出 k 名工程师,但是我们既要使他们的速度和越大,又要使这 k 名工程师的效率值的最小值越大,我们没法单纯对其中一个变量排序。这里我的思路是把工程师的速度 i 和效率 j 组合成一个二维数组 engineer[i][j],然后对这个二维数组按照效率值降序排序,这样我每遇到一个工程师 engineer[i],他一定是当前我已经遇到过的工程师里效率最低的那个。
遍历二维数组,将每个工程师的速度 i 加入最小堆,并把当前工程师的速度加到最后表现值的计算当中。当堆中元素个数 >= k 的时候,我们可以把速度最小的那个工程师弹出。具体细节参见代码。
时间O(nlogk)
空间O(k)
Java实现
1 class Solution { 2 public int maxPerformance(int n, int[] speed, int[] efficiency, int k) { 3 int MOD = (int) Math.pow(10, 9) + 7; 4 // [efficiency, speed] 5 int[][] engineers = new int[n][2]; 6 for (int i = 0; i < n; i++) { 7 engineers[i][0] = efficiency[i]; 8 engineers[i][1] = speed[i]; 9 } 10 // sort the efficiency in decreasing order 11 Arrays.sort(engineers, (a, b) -> b[0] - a[0]); 12 PriorityQueue<Integer> queue = new PriorityQueue<>(); 13 long tPerformance = 0; 14 long tSpeed = 0; 15 for (int i = 0; i < n; i++) { 16 if (queue.size() >= k) { 17 tSpeed -= queue.poll(); 18 } 19 queue.offer(engineers[i][1]); 20 tSpeed += engineers[i][1]; 21 tPerformance = Math.max(tPerformance, tSpeed * engineers[i][0]); 22 } 23 return (int) (tPerformance % MOD); 24 } 25 }