Skip to content

Commit c09b702

Browse files
authored
Merge pull request #110 from BrianLusina/feat/algorithms-max-runtime-for-n
feat(algorithms, binary-search): max runtime for n computers
2 parents b367a0b + 54c6e00 commit c09b702

16 files changed

+181
-0
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@
9393
* [Petethebaker](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/petethebaker.py)
9494
* Search
9595
* Binary Search
96+
* Maxruntime N Computers
97+
* [Test Max Runtime](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/search/binary_search/maxruntime_n_computers/test_max_runtime.py)
9698
* [Test Binary Search](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/search/binary_search/test_binary_search.py)
9799
* Interpolation
98100
* [Test Interpolation Search](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/search/interpolation/test_interpolation_search.py)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Maximum Running Time of N Computers
2+
3+
You are given an integer, n, representing the number of computers, and a 0-indexed integer array, batteries, where
4+
batteries[i] denotes the number of minutes the ith battery can power a computer.
5+
6+
Your goal is to run all n computers simultaneously for the maximum possible number of minutes using the available
7+
batteries.
8+
9+
Initially, you may assign at most one battery to each computer. After that, at any moment, you may remove a battery
10+
from a computer and replace it with another battery—either an unused battery or one taken from another computer.
11+
This replacement process can be repeated any number of times and takes no time.
12+
13+
Each battery can power any computer multiple times, but only until it is completely drained. Batteries cannot be
14+
recharged.
15+
16+
Return the maximum number of minutes you can run all n computers simultaneously.
17+
18+
Constraints:
19+
20+
- 1 ≤ `n``batteries.length` ≤ 10^5
21+
- 1 ≤ `batteries[i]` ≤ 10^5
22+
23+
## Examples
24+
25+
![Example 1](images/examples/max_runtime_n_computers_example_1.png)
26+
![Example 2](images/examples/max_runtime_n_computers_example_2.png)
27+
![Example 3](images/examples/max_runtime_n_computers_example_3.png)
28+
29+
## Solution
30+
31+
This solution aims to find the maximum number of minutes all `n` computers can run simultaneously using a set of batteries.
32+
We use a modified binary search pattern on the possible runtime values to achieve this. The key observation is that if
33+
it’s possible to run all n computers for x minutes, it is also possible to run them for any time less than `x`. This
34+
monotonic property makes binary search applicable. To solve this, we set the search space from 0 to `total_power // n`,
35+
where `total_power` is the sum of all battery capacities. At each step, we check whether running all computers for mid
36+
minutes is feasible by verifying that the sum of the available battery contributions (each battery contributing up to
37+
mid minutes) is at least `n * mid`. This feasibility check helps us efficiently narrow down the maximum achievable runtime.
38+
39+
Now, let’s look at the solution steps below:
40+
41+
1. Set `left=0` and `right=sum(batteries) // n` to define the minimum and maximum possible simultaneous runtime.
42+
2. While `left < right`:
43+
- Calculate `mid = right - (rught - left) // 2` (biases the midpoint toward the higher end to avoid infinite loops).
44+
- Initialize `usable=0` to store the sum of usable power
45+
- For each battery, add `min(b, mid)` to `usable`
46+
- If `usable >= mid * n`, the target feasible, so set `left=mid` to search for a longer time.
47+
- Otherwise, set `right = mid-1` to search in the lower half
48+
3. After the loop completes, `left` holds the maximum number of minutes that all `n` computers can run simultaneously.
49+
50+
![Solution 1](images/solution/max_runtime_n_computers_solution_1.png)
51+
![Solution 2](images/solution/max_runtime_n_computers_solution_2.png)
52+
![Solution 3](images/solution/max_runtime_n_computers_solution_3.png)
53+
![Solution 4](images/solution/max_runtime_n_computers_solution_4.png)
54+
![Solution 5](images/solution/max_runtime_n_computers_solution_5.png)
55+
![Solution 6](images/solution/max_runtime_n_computers_solution_6.png)
56+
![Solution 7](images/solution/max_runtime_n_computers_solution_7.png)
57+
![Solution 8](images/solution/max_runtime_n_computers_solution_8.png)
58+
![Solution 9](images/solution/max_runtime_n_computers_solution_9.png)
59+
60+
### Time Complexity
61+
62+
The time complexity of the solution is `O(n⋅logT)`), where `n` is the number of batteries and `T` is the total power of
63+
one computer, `T = sum(batteries) // n)`. This is because binary search runs in `O(logT)` iterations, and in each
64+
iteration, we compute the usable power by iterating through all `n` batteries, which takes `O(n)` time.
65+
66+
### Space Complexity
67+
68+
The space complexity of the solution os `O(1)` because no extra space is used
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from typing import List
2+
3+
4+
def max_runtime(batteries: List[int], n: int) -> int:
5+
"""
6+
Determines the maximum runtime of n computers given the power available from each battery.
7+
8+
The function uses binary search to find the maximum runtime that can power n computers for the given amount of time.
9+
10+
The function takes a list of integers representing the power available from each battery and an integer representing
11+
the number of computers to power.
12+
13+
The function returns an integer representing the maximum runtime that can power the computers for the given amount of time.
14+
15+
:param batteries: A list of integers representing the power available from each battery.
16+
:param n: An integer representing the number of computers to power.
17+
18+
:return: An integer representing the maximum runtime that can power the computers for the given amount of time.
19+
"""
20+
left = 0
21+
right = sum(batteries) // n
22+
result = 0
23+
24+
while left <= right:
25+
mid = (left + right) // 2
26+
27+
if can_run_for(batteries, n, mid):
28+
left = mid + 1
29+
result = mid
30+
else:
31+
right = mid - 1
32+
33+
return result
34+
35+
36+
def can_run_for(batteries: List[int], n: int, target_time: int) -> bool:
37+
"""
38+
Determines whether the given list of batteries can power n computers for the given amount of time.
39+
40+
:param batteries: A list of integers representing the power available from each battery.
41+
:param n: An integer representing the number of computers to power.
42+
:param target_time: An integer representing the amount of time to power the computers for.
43+
44+
:return: A boolean indicating whether the batteries can power the computers for the given amount of time.
45+
"""
46+
power_needed = n * target_time
47+
power_available = sum(min(battery, target_time) for battery in batteries)
48+
return power_available >= power_needed
49+
50+
51+
def max_run_time_2(batteries: List[int], n: int) -> int:
52+
53+
"""
54+
Finds the maximum runtime that can power the computers for the given amount of time.
55+
56+
:param batteries: A list of integers representing the power available from each battery.
57+
:param n: An integer representing the number of computers to power.
58+
59+
:return: An integer representing the maximum runtime that can power the computers for the given amount of time.
60+
"""
61+
62+
total_power = sum(batteries)
63+
left, right = 0, total_power // n
64+
65+
while left < right:
66+
mid = right - (right - left) // 2
67+
usable = sum(min(b, mid) for b in batteries)
68+
69+
if usable >= mid * n:
70+
left = mid
71+
else:
72+
right = mid - 1
73+
return left
38.2 KB
Loading
35.7 KB
Loading
31.8 KB
Loading
13.7 KB
Loading
33.1 KB
Loading
24.6 KB
Loading
44.9 KB
Loading

0 commit comments

Comments
 (0)