[Question] 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
).
Example 1:
Input: nums = [1,2,5,9], threshold = 6 Output: 5 Explanation: 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).
// TC: O(N⋅logM)
// SC: O(1)
// Return the sum of division results with 'divisor'.
func findDivisionSum(_ nums: [Int], _ divisor: Int) -> Int {
var result: Int = 0
for num in nums {
result += Int(ceil(Double(num) / Double(divisor))) // Get Higher/ Ceil Value
}
return result
}
func smallestDivisor(_ nums: [Int], _ threshold: Int) -> Int {
var low: Int = 1
var high: Int = 0
for num in nums {
high = max(high, num)
}
// Iterate using binary search on all divisors.
while low <= high {
let mid: Int = (low + high) / 2
let result: Int = findDivisionSum(nums, mid)
// If current divisor does not exceed threshold,
// then it can be our answer, but also try smaller divisors
// thus change search space to left half.
if result <= threshold {
high = mid - 1
}
// Otherwise, we need a bigger divisor to reduce the result sum
// thus change search space to right half.
else {
low = mid + 1
}
}
return low
}
let ipArraySmallDivision = [1,2,5,9]
let divisiorThreshold = 6
let opDivisior = smallestDivisor(ipArraySmallDivision, divisiorThreshold)
print("opDivisior--- ", opDivisior) // 5