Skip to content

feat: add solutions to lc problem: No.2071 #4382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,69 @@ func maxTaskAssign(tasks []int, workers []int, pills int, strength int) int {
}
```

#### TypeScript

```ts
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;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,21 @@ The last pill is not given because it will not make any worker strong enough for

<!-- solution:start -->

### Solution 1
### Solution 1: Greedy + Binary Search

Sort the tasks in ascending order of completion time and the workers in ascending order of ability.

Suppose the number of tasks we want to assign is $x$. We can greedily assign the first $x$ tasks to the $x$ workers with the highest strength. If it is possible to complete $x$ tasks, then it is also possible to complete $x-1$, $x-2$, $x-3$, ..., $1$, $0$ tasks. Therefore, we can use binary search to find the maximum $x$ such that it is possible to complete $x$ tasks.

We define a function $check(x)$ to determine whether it is possible to complete $x$ tasks.

The implementation of $check(x)$ is as follows:

Iterate through the $x$ workers with the highest strength in ascending order. Let the current worker being processed be $j$. The current available tasks must satisfy $tasks[i] \leq workers[j] + strength$.

If the smallest required strength task $task[i]$ among the current available tasks is less than or equal to $workers[j]$, then worker $j$ can complete task $task[i]$ without using a pill. Otherwise, the current worker must use a pill. If there are pills remaining, use one pill and complete the task with the highest required strength among the current available tasks. Otherwise, return `false`.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$, where $n$ is the number of tasks.

<!-- tabs:start -->

Expand Down Expand Up @@ -272,6 +286,69 @@ func maxTaskAssign(tasks []int, workers []int, pills int, strength int) int {
}
```

#### TypeScript

```ts
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;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
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;
}