Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You have n tasks and m workers. Each task has a strength requirement stored in a 0-indexed integer array tasks, with the ith task requiring tasks[i] strength to complete. The strength of each worker is stored in a 0-indexed integer array workers, with the jth worker having workers[j] strength. Each worker can only be assigned to a single task and must have a strength greater than or equal to the task's strength requirement (i.e., workers[j] >= tasks[i]).
Additionally, you have pills magical pills that will increase a worker's strength by strength. You can decide which workers receive the magical pills, however, you may only give each worker at most one magical pill.
Given the 0-indexed integer arrays tasks and workers and the integers pills and strength, return the maximum number of tasks that can be completed.
Example 1:
Input: tasks = [3,2,1], workers = [0,3,3], pills = 1, strength = 1 Output: 3 Explanation: We can assign the magical pill and tasks as follows: - Give the magical pill to worker 0. - Assign worker 0 to task 2 (0 + 1 >= 1) - Assign worker 1 to task 1 (3 >= 2) - Assign worker 2 to task 0 (3 >= 3)
Example 2:
Input: tasks = [5,4], workers = [0,0,0], pills = 1, strength = 5 Output: 1 Explanation: We can assign the magical pill and tasks as follows: - Give the magical pill to worker 0. - Assign worker 0 to task 0 (0 + 5 >= 5)
Example 3:
Input: tasks = [10,15,30], workers = [0,10,10,10,10], pills = 3, strength = 10 Output: 2 Explanation: We can assign the magical pills and tasks as follows: - Give the magical pill to worker 0 and worker 1. - Assign worker 0 to task 0 (0 + 10 >= 10) - Assign worker 1 to task 1 (10 + 10 >= 15) The last pill is not given because it will not make any worker strong enough for the last task.
Constraints:
n == tasks.lengthm == workers.length1 <= n, m <= 5 * 1040 <= pills <= m0 <= tasks[i], workers[j], strength <= 109Problem summary: You have n tasks and m workers. Each task has a strength requirement stored in a 0-indexed integer array tasks, with the ith task requiring tasks[i] strength to complete. The strength of each worker is stored in a 0-indexed integer array workers, with the jth worker having workers[j] strength. Each worker can only be assigned to a single task and must have a strength greater than or equal to the task's strength requirement (i.e., workers[j] >= tasks[i]). Additionally, you have pills magical pills that will increase a worker's strength by strength. You can decide which workers receive the magical pills, however, you may only give each worker at most one magical pill. Given the 0-indexed integer arrays tasks and workers and the integers pills and strength, return the maximum number of tasks that can be completed.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Two Pointers · Binary Search · Greedy · Monotonic Queue
[3,2,1] [0,3,3] 1 1
[5,4] [0,0,0] 1 5
[10,15,30] [0,10,10,10,10] 3 10
most-profit-assigning-work)maximum-running-time-of-n-computers)maximum-number-of-robots-within-budget)maximum-matching-of-players-with-trainers)maximize-the-minimum-powered-city)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2071: Maximum Number of Tasks You Can Assign
class Solution {
private int[] tasks;
private int[] workers;
private int strength;
private int pills;
private int m;
private int n;
public int maxTaskAssign(int[] tasks, int[] workers, int pills, int strength) {
Arrays.sort(tasks);
Arrays.sort(workers);
this.tasks = tasks;
this.workers = workers;
this.strength = strength;
this.pills = pills;
n = tasks.length;
m = workers.length;
int left = 0, right = Math.min(m, n);
while (left < right) {
int mid = (left + right + 1) >> 1;
if (check(mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
private boolean check(int x) {
int i = 0;
Deque<Integer> q = new ArrayDeque<>();
int p = pills;
for (int j = m - x; j < m; ++j) {
while (i < x && tasks[i] <= workers[j] + strength) {
q.offer(tasks[i++]);
}
if (q.isEmpty()) {
return false;
}
if (q.peekFirst() <= workers[j]) {
q.pollFirst();
} else if (p == 0) {
return false;
} else {
--p;
q.pollLast();
}
}
return true;
}
}
// Accepted solution for LeetCode #2071: Maximum Number of Tasks You Can Assign
func maxTaskAssign(tasks []int, workers []int, pills int, strength int) int {
sort.Ints(tasks)
sort.Ints(workers)
n, m := len(tasks), len(workers)
left, right := 0, min(m, n)
check := func(x int) bool {
p := pills
q := []int{}
i := 0
for j := m - x; j < m; j++ {
for i < x && tasks[i] <= workers[j]+strength {
q = append(q, tasks[i])
i++
}
if len(q) == 0 {
return false
}
if q[0] <= workers[j] {
q = q[1:]
} else if p == 0 {
return false
} else {
p--
q = q[:len(q)-1]
}
}
return true
}
for left < right {
mid := (left + right + 1) >> 1
if check(mid) {
left = mid
} else {
right = mid - 1
}
}
return left
}
# Accepted solution for LeetCode #2071: Maximum Number of Tasks You Can Assign
class Solution:
def maxTaskAssign(
self, tasks: List[int], workers: List[int], pills: int, strength: int
) -> int:
def check(x):
i = 0
q = deque()
p = pills
for j in range(m - x, m):
while i < x and tasks[i] <= workers[j] + strength:
q.append(tasks[i])
i += 1
if not q:
return False
if q[0] <= workers[j]:
q.popleft()
elif p == 0:
return False
else:
p -= 1
q.pop()
return True
n, m = len(tasks), len(workers)
tasks.sort()
workers.sort()
left, right = 0, min(n, m)
while left < right:
mid = (left + right + 1) >> 1
if check(mid):
left = mid
else:
right = mid - 1
return left
// Accepted solution for LeetCode #2071: Maximum Number of Tasks You Can Assign
/**
* [2071] Maximum Number of Tasks You Can Assign
*
* You have n tasks and m workers. Each task has a strength requirement stored in a 0-indexed integer array tasks, with the i^th task requiring tasks[i] strength to complete. The strength of each worker is stored in a 0-indexed integer array workers, with the j^th worker having workers[j] strength. Each worker can only be assigned to a single task and must have a strength greater than or equal to the task's strength requirement (i.e., workers[j] >= tasks[i]).
* Additionally, you have pills magical pills that will increase a worker's strength by strength. You can decide which workers receive the magical pills, however, you may only give each worker at most one magical pill.
* Given the 0-indexed integer arrays tasks and workers and the integers pills and strength, return the maximum number of tasks that can be completed.
*
* Example 1:
*
* Input: tasks = [<u>3</u>,<u>2</u>,<u>1</u>], workers = [<u>0</u>,<u>3</u>,<u>3</u>], pills = 1, strength = 1
* Output: 3
* Explanation:
* We can assign the magical pill and tasks as follows:
* - Give the magical pill to worker 0.
* - Assign worker 0 to task 2 (0 + 1 >= 1)
* - Assign worker 1 to task 1 (3 >= 2)
* - Assign worker 2 to task 0 (3 >= 3)
*
* Example 2:
*
* Input: tasks = [<u>5</u>,4], workers = [<u>0</u>,0,0], pills = 1, strength = 5
* Output: 1
* Explanation:
* We can assign the magical pill and tasks as follows:
* - Give the magical pill to worker 0.
* - Assign worker 0 to task 0 (0 + 5 >= 5)
*
* Example 3:
*
* Input: tasks = [<u>10</u>,<u>15</u>,30], workers = [<u>0</u>,<u>10</u>,10,10,10], pills = 3, strength = 10
* Output: 2
* Explanation:
* We can assign the magical pills and tasks as follows:
* - Give the magical pill to worker 0 and worker 1.
* - Assign worker 0 to task 0 (0 + 10 >= 10)
* - Assign worker 1 to task 1 (10 + 10 >= 15)
* The last pill is not given because it will not make any worker strong enough for the last task.
*
*
* Constraints:
*
* n == tasks.length
* m == workers.length
* 1 <= n, m <= 5 * 10^4
* 0 <= pills <= m
* 0 <= tasks[i], workers[j], strength <= 10^9
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/maximum-number-of-tasks-you-can-assign/
// discuss: https://leetcode.com/problems/maximum-number-of-tasks-you-can-assign/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
impl Solution {
pub fn max_task_assign(tasks: Vec<i32>, workers: Vec<i32>, pills: i32, strength: i32) -> i32 {
0
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_2071_example_1() {
let tasks = vec![3, 2, 1];
let workers = vec![0, 3, 3];
let pills = 1;
let strength = 1;
let result = 3;
assert_eq!(
Solution::max_task_assign(tasks, workers, pills, strength),
result
);
}
#[test]
#[ignore]
fn test_2071_example_2() {
let tasks = vec![5, 4];
let workers = vec![0, 0, 0];
let pills = 1;
let strength = 5;
let result = 1;
assert_eq!(
Solution::max_task_assign(tasks, workers, pills, strength),
result
);
}
#[test]
#[ignore]
fn test_2071_example_3() {
let tasks = vec![10, 15, 30];
let workers = vec![0, 10, 10, 10, 10];
let pills = 2;
let strength = 10;
let result = 2;
assert_eq!(
Solution::max_task_assign(tasks, workers, pills, strength),
result
);
}
}
// Accepted solution for LeetCode #2071: Maximum Number of Tasks You Can Assign
function maxTaskAssign(
tasks: number[],
workers: number[],
pills: number,
strength: number,
): number {
tasks.sort((a, b) => a - b);
workers.sort((a, b) => a - b);
const n = tasks.length;
const m = workers.length;
const check = (x: number): boolean => {
const dq = new Array<number>(x);
let head = 0;
let tail = 0;
const empty = () => head === tail;
const pushBack = (val: number) => {
dq[tail++] = val;
};
const popFront = () => {
head++;
};
const popBack = () => {
tail--;
};
const front = () => dq[head];
let i = 0;
let p = pills;
for (let j = m - x; j < m; j++) {
while (i < x && tasks[i] <= workers[j] + strength) {
pushBack(tasks[i]);
i++;
}
if (empty()) return false;
if (front() <= workers[j]) {
popFront();
} else {
if (p === 0) return false;
p--;
popBack();
}
}
return true;
};
let [left, right] = [0, Math.min(n, m)];
while (left < right) {
const mid = (left + right + 1) >> 1;
if (check(mid)) left = mid;
else right = mid - 1;
}
return left;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair of elements. The outer loop picks one element, the inner loop scans the rest. For n elements that is n × (n−1)/2 comparisons = O(n²). No extra memory — just two loop variables.
Each pointer traverses the array at most once. With two pointers moving inward (or both moving right), the total number of steps is bounded by n. Each comparison is O(1), giving O(n) overall. No auxiliary data structures are needed — just two index variables.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Advancing both pointers shrinks the search space too aggressively and skips candidates.
Usually fails on: A valid pair can be skipped when only one side should move.
Fix: Move exactly one pointer per decision branch based on invariant.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.
Wrong move: Locally optimal choices may fail globally.
Usually fails on: Counterexamples appear on crafted input orderings.
Fix: Verify with exchange argument or monotonic objective before committing.