Most Profit Assigning Work
MEDIUMDescription
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 theithjob, andworker[j]is the ability ofjthworker (i.e., thejthworker 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.lengthn == profit.lengthm == worker.length1 <= n, m <= 1041 <= difficulty[i], profit[i], worker[i] <= 105
Approaches
Checkout 3 different approaches to solve Most Profit Assigning Work. Click on different approaches to view the approach and algorithm in detail.
Two Pointers with Sorting
This is the most optimal approach. By sorting both the jobs (by difficulty) and the workers (by ability), we can iterate through them simultaneously using a two-pointer technique to find the maximum profit for each worker in a single pass.
Algorithm
- Create a list of
Jobobjects, each withdifficultyandprofit. - Sort the
jobslist bydifficulty. - Sort the
workerarray by ability. - Initialize
totalProfit = 0,maxProfitSoFar = 0, and a job pointerjobIndex = 0. - Iterate through each
abilityin the sortedworkerarray:- Use a
whileloop to advancejobIndexas long asjobs[jobIndex].difficulty <= ability. - Inside the
whileloop, updatemaxProfitSoFar = max(maxProfitSoFar, jobs[jobIndex].profit). - After the
whileloop, the current worker can achievemaxProfitSoFar. Add this tototalProfit.
- Use a
- Return
totalProfit.
The intuition is that if we process workers in increasing order of their ability, the set of jobs they can do is always a superset of the jobs the previous, less-able worker could do. This monotonicity allows for an efficient single-pass solution. First, we combine difficulty and profit into a list of Job objects. We sort this jobs list based on difficulty and also sort the worker array based on ability. We then use two pointers: one for iterating through the sorted workers (i) and another for the sorted jobs (jobIndex). We also maintain a variable maxProfitSoFar. For each worker, we advance the jobIndex to include all jobs they can perform, updating maxProfitSoFar along the way. The maxProfitSoFar for a worker is then added to the totalProfit. Since the next worker is more capable, we don't need to reset jobIndex or maxProfitSoFar, making the process very efficient.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
class Solution {
class Job {
int difficulty;
int profit;
Job(int difficulty, int profit) {
this.difficulty = difficulty;
this.profit = profit;
}
}
public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
int n = difficulty.length;
List<Job> jobs = new ArrayList<>();
for (int i = 0; i < n; i++) {
jobs.add(new Job(difficulty[i], profit[i]));
}
Collections.sort(jobs, (a, b) -> a.difficulty - b.difficulty);
Arrays.sort(worker);
int totalProfit = 0;
int maxProfitSoFar = 0;
int jobIndex = 0;
for (int ability : worker) {
while (jobIndex < n && jobs.get(jobIndex).difficulty <= ability) {
maxProfitSoFar = Math.max(maxProfitSoFar, jobs.get(jobIndex).profit);
jobIndex++;
}
totalProfit += maxProfitSoFar;
}
return totalProfit;
}
}
Complexity Analysis
Pros and Cons
- Most efficient solution in terms of time complexity.
- The main logic after sorting is a single linear scan (O(n+m)), which is very fast.
- Requires extra space (O(n)) to store the job objects.
- Modifies the order of the input
workerarray by sorting it (if sorting in-place).
Code Solutions
Checking out 3 solutions in different languages for Most Profit Assigning Work. Click on different languages to view the code.
class Solution {
public
int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
int n = difficulty.length;
List<int[]> job = new ArrayList<>();
for (int i = 0; i < n; ++i) {
job.add(new int[]{difficulty[i], profit[i]});
}
job.sort(Comparator.comparing(a->a[0]));
Arrays.sort(worker);
int res = 0;
int i = 0, t = 0;
for (int w : worker) {
while (i < n && job.get(i)[0] <= w) {
t = Math.max(t, job.get(i++)[1]);
}
res += t;
}
return res;
}
}
Video Solution
Watch the video walkthrough for Most Profit Assigning Work
Similar Questions
5 related questions you might find useful
Algorithms:
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.