Skip to content

Commit e571b11

Browse files
committed
LeetCode 2244. Minimum Rounds to Complete All Tasks
1 parent 951ec2a commit e571b11

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
374374
| [2131. Longest Palindrome by Concatenating Two Letter Words][lc2131] | 🟠 Medium | [![python](res/py.png)][lc2131py] |
375375
| [2136. Earliest Possible Day of Full Bloom][lc2136] | 🔴 Hard | [![python](res/py.png)][lc2136py] |
376376
| [2225. Find Players With Zero or One Losses][lc2225] | 🟢 Easy | [![python](res/py.png)][lc2225py] |
377+
| [2244. Minimum Rounds to Complete All Tasks][lc2244] | 🟠 Medium | [![python](res/py.png)][lc2244py] |
377378
| [2256. Minimum Average Difference][lc2256] | 🟠 Medium | [![python](res/py.png)][lc2256py] |
378379
| [2279. Maximum Bags With Full Capacity of Rocks][lc2279] | 🟠 Medium | [![python](res/py.png)][lc2279py] |
379380
| [2389. Longest Subsequence With Limited Sum][lc2389] | 🟢 Easy | [![python](res/py.png)][lc2389py] |
@@ -1100,6 +1101,8 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
11001101
[lc2136py]: leetcode/earliest-possible-day-of-full-bloom.py
11011102
[lc2225]: https://leetcode.com/problems/find-players-with-zero-or-one-losses/
11021103
[lc2225py]: leetcode/find-players-with-zero-or-one-losses.py
1104+
[lc2244]: https://leetcode.com/problems/minimum-rounds-to-complete-all-tasks/
1105+
[lc2244py]: leetcode/minimum-rounds-to-complete-all-tasks.py
11031106
[lc2256]: https://leetcode.com/problems/minimum-average-difference/
11041107
[lc2256py]: leetcode/minimum-average-difference.py
11051108
[lc2279]: https://leetcode.com/problems/maximum-bags-with-full-capacity-of-rocks/
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# 2244. Minimum Rounds to Complete All Tasks
2+
# 🟠 Medium
3+
#
4+
# https://leetcode.com/problems/minimum-rounds-to-complete-all-tasks/
5+
#
6+
# Tags: Array - Hash Table - Greedy - Counting
7+
8+
import timeit
9+
from collections import Counter
10+
from typing import List
11+
12+
13+
# We need to count the number of tasks of each difficulty, then greedily
14+
# group them in as many groups of 3 as possible with 0, 1 or 2 groups of
15+
# 2 at the end to place the remainder of freq % 3 if any. We can use
16+
# Counter to group the tasks by difficulty, then divide by 3 to obtain
17+
# the number of groups, if there is any remainder to the division, we
18+
# need to add one more group to the result.
19+
#
20+
# Time complexity: O(n) - We visit each element once, then iterate over
21+
# the frequencies that will be, at most n.
22+
# Space complexity: O(n) - The counter can grow in size with the input.
23+
#
24+
# Runtime 2133 ms Beats 44.76%
25+
# Memory 28.4 MB Beats 44.10%
26+
class UseDivMod:
27+
def minimumRounds(self, tasks: List[int]) -> int:
28+
frequencies = Counter(tasks)
29+
res = 0
30+
for frequency in frequencies.values():
31+
if frequency == 1:
32+
return -1
33+
q, rem = divmod(frequency, 3)
34+
res += q
35+
if rem:
36+
res += 1
37+
return res
38+
39+
40+
# Improve the previous solution using the division operation instead of
41+
# a call to divmod.
42+
#
43+
# Time complexity: O(n) - We visit each element once, then iterate over
44+
# the frequencies that will be, at most n.
45+
# Space complexity: O(n) - The counter can grow in size with the input.
46+
#
47+
# Runtime 1220 ms Beats 57.87%
48+
# Memory 28.2 MB Beats 82.79%
49+
class AddTwo:
50+
def minimumRounds(self, tasks: List[int]) -> int:
51+
frequencies = Counter(tasks)
52+
res = 0
53+
for freq in frequencies.values():
54+
if freq == 1:
55+
return -1
56+
res += (freq + 2) // 3
57+
return res
58+
59+
60+
# Same logic as the previous solution but condensed into two lines, one
61+
# to instantiate the counter, one to get the result.
62+
#
63+
# Time complexity: O(n) - We visit each element once, then iterate over
64+
# the frequencies that will be, at most n.
65+
# Space complexity: O(n) - The counter can grow in size with the input.
66+
#
67+
# Runtime 1779 ms Beats 48.4%
68+
# Memory 28.3 MB Beats 70.66%
69+
class Shorter:
70+
def minimumRounds(self, tasks: List[int]) -> int:
71+
frequencies = Counter(tasks).values()
72+
return (
73+
-1
74+
if 1 in frequencies
75+
else sum((freq + 2) // 3 for freq in frequencies)
76+
)
77+
78+
79+
def test():
80+
executors = [
81+
UseDivMod,
82+
AddTwo,
83+
Shorter,
84+
]
85+
tests = [
86+
[[2, 3, 3], -1],
87+
[[2, 2, 3, 3, 2, 4, 4, 4, 4, 4], 4],
88+
]
89+
for executor in executors:
90+
start = timeit.default_timer()
91+
for _ in range(1):
92+
for col, t in enumerate(tests):
93+
sol = executor()
94+
result = sol.minimumRounds(t[0])
95+
exp = t[1]
96+
assert result == exp, (
97+
f"\033[93m» {result} <> {exp}\033[91m for"
98+
+ f" test {col} using \033[1m{executor.__name__}"
99+
)
100+
stop = timeit.default_timer()
101+
used = str(round(stop - start, 5))
102+
cols = "{0:20}{1:10}{2:10}"
103+
res = cols.format(executor.__name__, used, "seconds")
104+
print(f"\033[92m» {res}\033[0m")
105+
106+
107+
test()

0 commit comments

Comments
 (0)