comments | difficulty | edit_url | tags | |||||
---|---|---|---|---|---|---|---|---|
true |
Medium |
|
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
We can sort the jobs in ascending order of ability, and then sort the jobs in ascending order of difficulty.
Then we traverse the workers. For each worker, we find the job with the maximum profit that he can complete, and then add this profit to the answer.
The time complexity is profit
and worker
respectively.
class Solution:
def maxProfitAssignment(
self, difficulty: List[int], profit: List[int], worker: List[int]
) -> int:
worker.sort()
jobs = sorted(zip(difficulty, profit))
ans = mx = i = 0
for w in worker:
while i < len(jobs) and jobs[i][0] <= w:
mx = max(mx, jobs[i][1])
i += 1
ans += mx
return ans
class Solution {
public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
Arrays.sort(worker);
int n = profit.length;
int[][] jobs = new int[n][0];
for (int i = 0; i < n; ++i) {
jobs[i] = new int[] {difficulty[i], profit[i]};
}
Arrays.sort(jobs, (a, b) -> a[0] - b[0]);
int ans = 0, mx = 0, i = 0;
for (int w : worker) {
while (i < n && jobs[i][0] <= w) {
mx = Math.max(mx, jobs[i++][1]);
}
ans += mx;
}
return ans;
}
}
class Solution {
public:
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
sort(worker.begin(), worker.end());
int n = profit.size();
vector<pair<int, int>> jobs;
for (int i = 0; i < n; ++i) {
jobs.emplace_back(difficulty[i], profit[i]);
}
sort(jobs.begin(), jobs.end());
int ans = 0, mx = 0, i = 0;
for (int w : worker) {
while (i < n && jobs[i].first <= w) {
mx = max(mx, jobs[i++].second);
}
ans += mx;
}
return ans;
}
};
func maxProfitAssignment(difficulty []int, profit []int, worker []int) (ans int) {
sort.Ints(worker)
n := len(profit)
jobs := make([][2]int, n)
for i, p := range profit {
jobs[i] = [2]int{difficulty[i], p}
}
sort.Slice(jobs, func(i, j int) bool { return jobs[i][0] < jobs[j][0] })
mx, i := 0, 0
for _, w := range worker {
for ; i < n && jobs[i][0] <= w; i++ {
mx = max(mx, jobs[i][1])
}
ans += mx
}
return
}
function maxProfitAssignment(difficulty: number[], profit: number[], worker: number[]): number {
const n = profit.length;
worker.sort((a, b) => a - b);
const jobs = Array.from({ length: n }, (_, i) => [difficulty[i], profit[i]]);
jobs.sort((a, b) => a[0] - b[0]);
let [ans, mx, i] = [0, 0, 0];
for (const w of worker) {
while (i < n && jobs[i][0] <= w) {
mx = Math.max(mx, jobs[i++][1]);
}
ans += mx;
}
return ans;
}
Let's denote
Then, we iterate over the jobs, and for each job
Next, we iterate from
Finally, we iterate over the workers, and for each worker
The time complexity is profit
array, and difficulty
array.
class Solution:
def maxProfitAssignment(
self, difficulty: List[int], profit: List[int], worker: List[int]
) -> int:
m = max(difficulty)
f = [0] * (m + 1)
for d, p in zip(difficulty, profit):
f[d] = max(f[d], p)
for i in range(1, m + 1):
f[i] = max(f[i], f[i - 1])
return sum(f[min(w, m)] for w in worker)
class Solution {
public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
int m = Arrays.stream(difficulty).max().getAsInt();
int[] f = new int[m + 1];
int n = profit.length;
for (int i = 0; i < n; ++i) {
int d = difficulty[i];
f[d] = Math.max(f[d], profit[i]);
}
for (int i = 1; i <= m; ++i) {
f[i] = Math.max(f[i], f[i - 1]);
}
int ans = 0;
for (int w : worker) {
ans += f[Math.min(w, m)];
}
return ans;
}
}
class Solution {
public:
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
int m = *max_element(begin(difficulty), end(difficulty));
int f[m + 1];
memset(f, 0, sizeof(f));
int n = profit.size();
for (int i = 0; i < n; ++i) {
int d = difficulty[i];
f[d] = max(f[d], profit[i]);
}
for (int i = 1; i <= m; ++i) {
f[i] = max(f[i], f[i - 1]);
}
int ans = 0;
for (int w : worker) {
ans += f[min(w, m)];
}
return ans;
}
};
func maxProfitAssignment(difficulty []int, profit []int, worker []int) (ans int) {
m := slices.Max(difficulty)
f := make([]int, m+1)
for i, d := range difficulty {
f[d] = max(f[d], profit[i])
}
for i := 1; i <= m; i++ {
f[i] = max(f[i], f[i-1])
}
for _, w := range worker {
ans += f[min(w, m)]
}
return
}
function maxProfitAssignment(difficulty: number[], profit: number[], worker: number[]): number {
const m = Math.max(...difficulty);
const f = Array(m + 1).fill(0);
const n = profit.length;
for (let i = 0; i < n; ++i) {
const d = difficulty[i];
f[d] = Math.max(f[d], profit[i]);
}
for (let i = 1; i <= m; ++i) {
f[i] = Math.max(f[i], f[i - 1]);
}
return worker.reduce((acc, w) => acc + f[Math.min(w, m)], 0);
}