原文链接: https://leetcode-cn.com/problems/most-profit-assigning-work
英文原文
You have n
jobs and m
workers. You are given three arrays: difficulty
, profit
, and worker
where:
difficulty[i]
andprofit[i]
are the difficulty and the profit of theith
job, andworker[j]
is the ability ofjth
worker (i.e., thejth
worker can only complete a job with difficulty at mostworker[j]
).
Every worker can be assigned at most one job, but one job can be completed multiple times.
- For example, if three workers attempt the same job that pays
$1
, then the total profit will be$3
. If a worker cannot complete any job, their profit is$0
.
Return the maximum profit we can achieve after assigning the workers to the jobs.
Example 1:
Input: difficulty = [2,4,6,8,10], profit = [10,20,30,40,50], worker = [4,5,6,7] Output: 100 Explanation: Workers are assigned jobs of difficulty [4,4,6,6] and they get a profit of [20,20,30,30] separately.
Example 2:
Input: difficulty = [85,47,57], profit = [24,66,99], worker = [40,25,25] Output: 0
Constraints:
n == difficulty.length
n == profit.length
m == worker.length
1 <= n, m <= 104
1 <= difficulty[i], profit[i], worker[i] <= 105
中文题目
有一些工作:difficulty[i]
表示第 i
个工作的难度,profit[i]
表示第 i
个工作的收益。
现在我们有一些工人。worker[i]
是第 i
个工人的能力,即该工人只能完成难度小于等于 worker[i]
的工作。
每一个工人都最多只能安排一个工作,但是一个工作可以完成多次。
举个例子,如果 3 个工人都尝试完成一份报酬为 1 的同样工作,那么总收益为 $3。如果一个工人不能完成任何工作,他的收益为 $0 。
我们能得到的最大收益是多少?
示例 1:
输入: difficulty = [2,4,6,8,10], profit = [10,20,30,40,50], worker = [4,5,6,7] 输出: 100 解释: 工人被分配的工作难度是 [4,4,6,6] ,分别获得 [20,20,30,30] 的收益。
示例 2:
输入: difficulty = [85,47,57], profit = [24,66,99], worker = [40,25,25] 输出: 0
提示:
n == difficulty.length
n == profit.length
m == worker.length
1 <= n, m <= 104
1 <= difficulty[i], profit[i], worker[i] <= 105
通过代码
官方题解
方法:排序
想法
我们可以以任意顺序考虑工人,所以我们按照能力大小排序。
如果我们先访问低难度的工作,那么收益一定是截至目前最好的。
算法
我们使用 “双指针” 的方法去安排任务。我们记录最大可用利润 best
。对于每个能力值为 skill
的工人,找到难度小于等于能力值的任务,并将如结果中。
import java.awt.Point;
class Solution {
public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
int N = difficulty.length;
Point[] jobs = new Point[N];
for (int i = 0; i < N; ++i)
jobs[i] = new Point(difficulty[i], profit[i]);
Arrays.sort(jobs, (a, b) -> a.x - b.x);
Arrays.sort(worker);
int ans = 0, i = 0, best = 0;
for (int skill: worker) {
while (i < N && skill >= jobs[i].x)
best = Math.max(best, jobs[i++].y);
ans += best;
}
return ans;
}
}
class Solution(object):
def maxProfitAssignment(self, difficulty, profit, worker):
jobs = zip(difficulty, profit)
jobs.sort()
ans = i = best = 0
for skill in sorted(worker):
while i < len(jobs) and skill >= jobs[i][0]:
best = max(best, jobs[i][1])
i += 1
ans += best
return ans
复杂度分析
- 时间复杂度:$O(N \log N + Q \log Q)$,其中 $N$ 是任务个数,$Q$ 是工人数量。
- 空间复杂度:$O(N)$,
jobs
的额外空间。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
8437 | 22263 | 37.9% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|