Problem

You are given an integer array workers, where workers[i] represents the skill level of the ith worker. You are also given a 2D integer array tasks, where:

  • tasks[i][0] represents the skill requirement needed to complete the task.
  • tasks[i][1] represents the profit earned from completing the task.

Each worker can complete at most one task, and they can only take a task if their skill level is equal to the task’s skill requirement. An additional worker joins today who can take up any task, regardless of the skill requirement.

Return the maximum total profit that can be earned by optimally assigning the tasks to the workers.

Examples

Example 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Input: workers = [1,2,3,4,5], tasks = [[1,100],[2,400],[3,100],[3,400]]

Output: 1000

Explanation:

Worker 0 completes task 0.
Worker 1 completes task 1.
Worker 2 completes task 3.
The additional worker completes task 2.

Example 2

1
2
3
4
5
6
7
Input: workers = [10,10000,100000000], tasks = [[1,100]]

Output: 100

Explanation:

Since no worker matches the skill requirement, only the additional worker can complete task 0.

Example 3

1
2
3
4
5
6
7
Input: workers = [7], tasks = [[3,3],[3,3]]

Output: 3

Explanation:

The additional worker completes task 1. Worker 0 cannot work since no task has a skill requirement of 7.

Constraints

  • 1 <= workers.length <= 10^5
  • 1 <= workers[i] <= 10^9
  • 1 <= tasks.length <= 10^5
  • tasks[i].length == 2
  • 1 <= tasks[i][0], tasks[i][1] <= 10^9

Solution

Method 1 – Greedy with Sorting and Two Pointers

Intuition

To maximize profit, assign the most profitable tasks to the most skilled workers. Sort both arrays and pair the largest profits with the largest skills.

Approach

  1. Sort the profit array in descending order.
  2. Sort the worker array in descending order.
  3. Assign the highest profit task to the highest skill worker, the next highest to the next, and so on, until one of the arrays is exhausted.
  4. Sum the assigned profits.
  5. Return the total profit.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution {
public:
    int maxProfitAssignment(vector<int>& profit, vector<int>& worker) {
        sort(profit.rbegin(), profit.rend());
        sort(worker.rbegin(), worker.rend());
        int n = min(profit.size(), worker.size()), ans = 0;
        for (int i = 0; i < n; ++i) ans += profit[i] * worker[i];
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
    public int maxProfitAssignment(int[] profit, int[] worker) {
        Arrays.sort(profit);
        Arrays.sort(worker);
        int n = Math.min(profit.length, worker.length), ans = 0;
        for (int i = 0; i < n; i++) {
            ans += profit[profit.length-1-i] * worker[worker.length-1-i];
        }
        return ans;
    }
}
1
2
3
4
5
6
7
8
class Solution:
    def maxProfitAssignment(self, profit: list[int], worker: list[int]) -> int:
        profit.sort(reverse=True)
        worker.sort(reverse=True)
        ans = 0
        for p, w in zip(profit, worker):
            ans += p * w
        return ans

Complexity

  • ⏰ Time complexity: O(n log n) — for sorting both arrays.
  • 🧺 Space complexity: O(1) — extra space for variables only.