Find the Smallest Divisor Given a Threshold

[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⋅log⁡M)
// 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

Leave a Comment

Your email address will not be published. Required fields are marked *