Given an array of integers nums
and an integer threshold
, we will choose a positive integer divisor
, divide all the array by it, and sum the division's result. Find the smallest divisor
such that the result mentioned above is less than or equal to threshold
.
Each result of the division is rounded to the nearest integer greater than or equal to that element. (For example: 7/3 = 3
and 10/2 = 5
).
For example:
nums = [1,2,5,9], threshold = 6
. The output is 5. We can get a sum to 17 (1+2+5+9) if the divisor is 1. If the divisor is 4 we can get a sum of 7 (1+1+2+3) and if the divisor is 5 the sum will be 5 (1+1+1+2).
As another example,
nums = [44,22,33,11,1], threshold = 5
. The output is 44.
What is the most efficient way to solve this problem?
A brute-force approach would be to iterate through all possible divisors starting from 1 up to the maximum value in the nums
array. For each divisor, calculate the sum of the ceiling of each number divided by the divisor. If the sum is less than or equal to the threshold
, return that divisor. Since we want the smallest divisor, we can stop and return the first divisor that satisfies the condition.
def solve(nums, threshold):
max_num = max(nums)
for divisor in range(1, max_num + 1):
sum_val = 0
for num in nums:
sum_val += (num + divisor - 1) // divisor # Ceiling division
if sum_val <= threshold:
return divisor
return -1 # Should not reach here based on problem constraints
O(M * N), where M is the maximum value in nums
and N is the length of nums
. We iterate up to max(nums)
and for each potential divisor, iterate through nums
.
O(1), as we use only a constant amount of extra space.
Since the problem statement guarantees that a solution exists, and the divisor must be between 1 and the maximum element in nums
, we can use binary search to efficiently find the smallest divisor that satisfies the condition. The search space is the range [1, max(nums)].
left
to 1 and right
to the maximum element in nums
.left < right
, calculate mid = left + (right - left) // 2
.mid
as the divisor.threshold
, the divisor is too small. Update left = mid + 1
.right = mid
to search for an even smaller divisor.left == right
, left
(or right
) is the smallest divisor that satisfies the condition.def solve_optimal(nums, threshold):
left = 1
right = max(nums)
while left < right:
mid = left + (right - left) // 2
sum_val = 0
for num in nums:
sum_val += (num + mid - 1) // mid
if sum_val > threshold:
left = mid + 1
else:
right = mid
return left
O(N * log(M)), where N is the length of nums
and M is the maximum value in nums
. We perform binary search on the range [1, max(nums)], and for each potential divisor, we iterate through nums
to calculate the sum of divisions.
O(1), as we use only a constant amount of extra space.
1 <= nums.length
, so we don't need to handle an empty input array.nums
has only one element.