Skip to content

Commit 2c5ec48

Browse files
committed
feat: add solutions to lc problem: No.2071
No.2071.Maximum Number of Tasks You Can Assign
1 parent 1a7ccdb commit 2c5ec48

File tree

8 files changed

+546
-7
lines changed

8 files changed

+546
-7
lines changed

solution/0000-0099/0036.Valid Sudoku/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@
7878

7979
- 每一行中的数字都不重复;
8080
- 每一列中的数字都不重复;
81-
- 每一个 `3*3` 宫格中的数字都不重复
81+
- 每一个 $3 \times 3$ 的宫格中的数字都不重复
8282

83-
遍历数独,对于每个数字,判断其所在的行、列`3*3` 宫格是否已经出现过该数字,如果是,则返回 `false`。遍历结束,返回 `true`
83+
遍历数独,对于每个数字,判断其所在的行、列 以及 $3 \times 3$ 的宫格是否已经出现过该数字,如果是,则返回 `false`。遍历结束,返回 `true`
8484

8585
时间复杂度 $O(C)$,空间复杂度 $O(C)$,其中 $C$ 是数独中的空格数。本题中 $C=81$。
8686

solution/0200-0299/0240.Search a 2D Matrix II/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@
5959

6060
这里我们以左下角作为起始搜索点,往右上方向开始搜索,比较当前元素 `matrix[i][j]``target` 的大小关系:
6161

62-
-`matrix[i][j] == target`,说明找到了目标值,直接返回 true。
63-
-`matrix[i][j] > target`,说明这一行从当前位置开始往右的所有元素均大于 target,应该让 i 指针往上移动,即 `i--`
64-
-`matrix[i][j] < target`,说明这一列从当前位置开始往上的所有元素均小于 target,应该让 j 指针往右移动,即 `j++`
62+
-`matrix[i][j] == target`,说明找到了目标值,直接返回 `true`
63+
-`matrix[i][j] > target`,说明这一行从当前位置开始往右的所有元素均大于 `target`,应该让 $i$ 指针往上移动,即 $i \leftarrow i - 1$
64+
-`matrix[i][j] < target`,说明这一列从当前位置开始往上的所有元素均小于 `target`,应该让 $j$ 指针往右移动,即 $j \leftarrow j + 1$
6565

66-
若搜索结束依然找不到 target,返回 false。
66+
若搜索结束依然找不到 `target`,返回 `false`
6767

6868
时间复杂度 $O(m + n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数。
6969

solution/2000-2099/2071.Maximum Number of Tasks You Can Assign/README.md

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,215 @@
7575

7676
<!-- 这里可写通用的实现逻辑 -->
7777

78+
**方法一:贪心 + 二分查找**
79+
80+
将任务按照完成时间从小到大排序,将工人按照能力从小到大排序。
81+
82+
假设我们要安排的任务数为 $x$,那么我们可以贪心地将前 $x$ 个任务分配给力量值最大的 $x$ 个工人。假设能完成任务数为 $x$,那么也一定能完成任务数为 $x-1$,$x-2$,$x-3$,…,$1$,$0$ 的情况。因此,我们可以使用二分查找的方法,找到最大的 $x$,使得能够完成任务数为 $x$ 的情况。
83+
84+
我们定义一个函数 $check(x)$,表示是否能够完成任务数为 $x$ 的情况。
85+
86+
函数 $check(x)$ 的实现如下:
87+
88+
从小到大遍历力量值最大的 $x$ 个工人,记当前遍历到的工人为 $j$,那么当前可选任务必须满足 $tasks[i] \leq workers[j] + strength$。
89+
90+
如果当前可选任务中要求力量值最小的一个 $task[i]$ 小于等于 $workers[j]$,那么第 $j$ 个工人不用吃药就可以完成任务 $task[i]$。否则,当前工人必须吃药,如果还有药丸,那么吃药,并且在当前可选任务中选择要求力量值最大的一个任务完成。否则,返回 `false`
91+
92+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为任务数。
93+
7894
<!-- tabs:start -->
7995

8096
### **Python3**
8197

8298
<!-- 这里可写当前语言的特殊实现逻辑 -->
8399

84100
```python
85-
101+
class Solution:
102+
def maxTaskAssign(self, tasks: List[int], workers: List[int], pills: int, strength: int) -> int:
103+
def check(x):
104+
i = 0
105+
q = deque()
106+
p = pills
107+
for j in range(m - x, m):
108+
while i < x and tasks[i] <= workers[j] + strength:
109+
q.append(tasks[i])
110+
i += 1
111+
if not q:
112+
return False
113+
if q[0] <= workers[j]:
114+
q.popleft()
115+
elif p == 0:
116+
return False
117+
else:
118+
p -= 1
119+
q.pop()
120+
return True
121+
122+
n, m = len(tasks), len(workers)
123+
tasks.sort()
124+
workers.sort()
125+
left, right = 0, min(n, m)
126+
while left < right:
127+
mid = (left + right + 1) >> 1
128+
if check(mid):
129+
left = mid
130+
else:
131+
right = mid - 1
132+
return left
86133
```
87134

88135
### **Java**
89136

90137
<!-- 这里可写当前语言的特殊实现逻辑 -->
91138

92139
```java
140+
class Solution {
141+
private int[] tasks;
142+
private int[] workers;
143+
private int strength;
144+
private int pills;
145+
private int m;
146+
private int n;
147+
148+
public int maxTaskAssign(int[] tasks, int[] workers, int pills, int strength) {
149+
Arrays.sort(tasks);
150+
Arrays.sort(workers);
151+
this.tasks = tasks;
152+
this.workers = workers;
153+
this.strength = strength;
154+
this.pills = pills;
155+
n = tasks.length;
156+
m = workers.length;
157+
int left = 0, right = Math.min(m, n);
158+
while (left < right) {
159+
int mid = (left + right + 1) >> 1;
160+
if (check(mid)) {
161+
left = mid;
162+
} else {
163+
right = mid - 1;
164+
}
165+
}
166+
return left;
167+
}
168+
169+
private boolean check(int x) {
170+
int i = 0;
171+
Deque<Integer> q = new ArrayDeque<>();
172+
int p = pills;
173+
for (int j = m - x; j < m; ++j) {
174+
while (i < x && tasks[i] <= workers[j] + strength) {
175+
q.offer(tasks[i++]);
176+
}
177+
if (q.isEmpty()) {
178+
return false;
179+
}
180+
if (q.peekFirst() <= workers[j]) {
181+
q.pollFirst();
182+
} else if (p == 0) {
183+
return false;
184+
} else {
185+
--p;
186+
q.pollLast();
187+
}
188+
}
189+
return true;
190+
}
191+
}
192+
```
193+
194+
### **C++**
195+
196+
```cpp
197+
class Solution {
198+
public:
199+
int maxTaskAssign(vector<int>& tasks, vector<int>& workers, int pills, int strength) {
200+
sort(tasks.begin(), tasks.end());
201+
sort(workers.begin(), workers.end());
202+
int n = tasks.size(), m = workers.size();
203+
int left = 0, right = min(m, n);
204+
auto check = [&](int x) {
205+
int p = pills;
206+
deque<int> q;
207+
int i = 0;
208+
for (int j = m - x; j < m; ++j) {
209+
while (i < x && tasks[i] <= workers[j] + strength) {
210+
q.push_back(tasks[i++]);
211+
}
212+
if (q.empty()) {
213+
return false;
214+
}
215+
if (q.front() <= workers[j]) {
216+
q.pop_front();
217+
} else if (p == 0) {
218+
return false;
219+
} else {
220+
--p;
221+
q.pop_back();
222+
}
223+
}
224+
return true;
225+
};
226+
while (left < right) {
227+
int mid = (left + right + 1) >> 1;
228+
if (check(mid)) {
229+
left = mid;
230+
} else {
231+
right = mid - 1;
232+
}
233+
}
234+
return left;
235+
}
236+
};
237+
```
93238
239+
### **Go**
240+
241+
```go
242+
func maxTaskAssign(tasks []int, workers []int, pills int, strength int) int {
243+
sort.Ints(tasks)
244+
sort.Ints(workers)
245+
n, m := len(tasks), len(workers)
246+
left, right := 0, min(m, n)
247+
check := func(x int) bool {
248+
p := pills
249+
q := []int{}
250+
i := 0
251+
for j := m - x; j < m; j++ {
252+
for i < x && tasks[i] <= workers[j]+strength {
253+
q = append(q, tasks[i])
254+
i++
255+
}
256+
if len(q) == 0 {
257+
return false
258+
}
259+
if q[0] <= workers[j] {
260+
q = q[1:]
261+
} else if p == 0 {
262+
return false
263+
} else {
264+
p--
265+
q = q[:len(q)-1]
266+
}
267+
}
268+
return true
269+
}
270+
for left < right {
271+
mid := (left + right + 1) >> 1
272+
if check(mid) {
273+
left = mid
274+
} else {
275+
right = mid - 1
276+
}
277+
}
278+
return left
279+
}
280+
281+
func min(a, b int) int {
282+
if a < b {
283+
return a
284+
}
285+
return b
286+
}
94287
```
95288

96289
### **...**

0 commit comments

Comments
 (0)