Given an array of integers nums and an integer limit as the threshold value, find the smallest positive integer divisor such that upon dividing all the elements of the array by this divisor, the sum of the division results is less than or equal to the threshold value.
Each result of the division is rounded up to the nearest integer greater than or equal to that element.
Input: nums = [1, 2, 3, 4, 5], limit = 8
Output: 3
Explanation: We can get a sum of 15(1 + 2 + 3 + 4 + 5) if we choose 1 as a divisor.
The sum is 9(1 + 1 + 2 + 2 + 3) if we choose 2 as a divisor. Upon dividing all the elements of the array by 3, we get 1,1,1,2,2 respectively. Now, their sum is equal to 7 <= 8 i.e. the threshold value. So, 3 is the minimum possible answer.
Input: nums = [8,4,2,3], limit = 10
Output: 2
Explanation: If we choose 1, we get 17 as the sum. If we choose 2, we get 9 (4+2+1+2) <= 10 as the answer. So, 2 is the answer.
Input: nums = [8,4,2,3], limit = 4
The extremely naive approach is to use linear search to check all possible divisors from 1 to maximum element of the array. The minimum number for which the result is less than or equal to threshold value(limit), will be our answer.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find the smallest divisor
int smallestDivisor(vector<int>& nums, int limit) {
// Size of array.
int n = nums.size();
// Find the maximum element in arr
int maxi = *max_element(nums.begin(), nums.end());
// Find the smallest divisor
for (int d = 1; d <= maxi; d++) {
int sum = 0;
/* Calculate the sum of ceil
(nums[i] / d) for all elements*/
for (int i = 0; i < n; i++) {
sum += ceil((double)nums[i] / (double)d);
}
// Check if the sum is <= limit
if (sum <= limit)
return d;
}
// Return -1 if no valid divisor found
return -1;
}
};
int main() {
vector<int> arr = {1, 2, 3, 4, 5};
int limit = 8;
// Create an object of the Solution class
Solution sol;
int ans = sol.smallestDivisor(arr, limit);
// Print the result
cout << "The minimum divisor is: " << ans << "\n";
return 0;
}
import java.util.*;
class Solution {
// Function to find the smallest divisor
public int smallestDivisor(int[] nums, int limit) {
// Size of array
int n = nums.length;
// Find the maximum element in nums
int maxi = Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
maxi = Math.max(maxi, nums[i]);
}
// Find the smallest divisor
for (int d = 1; d <= maxi; d++) {
int sum = 0;
/* Calculate the sum of ceil
(nums.get(i) / d) for all elements */
for (int i = 0; i < n; i++) {
sum += Math.ceil((double) nums[i] / (double)(d));
}
// Check if the sum is <= limit
if (sum <= limit)
return d;
}
// Return -1 if no valid divisor found
return -1;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
int limit = 8;
// Create an object of the Solution class
Solution sol = new Solution();
int ans = sol.smallestDivisor(nums, limit);
// Print the result
System.out.println("The minimum divisor is: " + ans);
}
}
import math
class Solution:
# Function to find the smallest divisor
def smallestDivisor(self, nums, limit):
# Size of array
n = len(nums)
# Find the maximum element in nums
maxi = max(nums)
# Find the smallest divisor
for d in range(1, maxi + 1):
sum = 0
""" Calculate the sum of ceil
(nums[i] / d) for all elements """
for num in nums:
sum += math.ceil(num / d)
# Check if the sum is <= limit
if sum <= limit:
return d
# Return -1 if no valid divisor found
return -1
if __name__ == "__main__":
nums = [1, 2, 3, 4, 5]
limit = 8
# Create an object of the Solution class
sol = Solution()
ans = sol.smallestDivisor(nums, limit)
# Print the result
print(f"The minimum divisor is: {ans}")
class Solution {
// Function to find the smallest divisor
smallestDivisor(nums, limit) {
// Size of array
let n = nums.length;
// Find the maximum element in nums
let maxi = Math.max(...nums);
// Find the smallest divisor
for (let d = 1; d <= maxi; d++) {
let sum = 0;
/* Calculate the sum of ceil
(nums[i] / d) for all elements */
for (let i = 0; i < n; i++) {
sum += Math.ceil(nums[i] / d);
}
// Check if the sum is <= limit
if (sum <= limit)
return d;
}
// Return -1 if no valid divisor found
return -1;
}
}
let arr = [1, 2, 3, 4, 5];
let limit = 8;
// Create an object of the Solution class
let sol = new Solution();
let ans = sol.smallestDivisor(arr, limit);
// Print the result
console.log(`The minimum divisor is: ${ans}`);
Here the idea is to use binary search to efficiently solve this problem by dividing the search space into halves. As, the search space of this probem is in the range[1, max], where max is the maximum element of the array. It can be considered as a sorted search space, hence binary search can be applied.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
/* Helper function to find the
summation of division values*/
int sumByD(vector<int>& nums, int limit) {
// Size of array
int n = nums.size();
// Find the summation of division values
int sum = 0;
for (int i = 0; i < n; i++) {
sum += ceil((double)(nums[i]) / (double)(limit));
}
return sum;
}
public:
// Function to find the smallest divisor
int smallestDivisor(vector<int>& nums, int limit) {
int n = nums.size();
if (n > limit) return -1;
// Initialize binary search bounds
int low = 1, high = *max_element(nums.begin(), nums.end());
// Apply binary search
while (low <= high) {
int mid = (low + high) / 2;
if (sumByD(nums, mid) <= limit) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
};
int main() {
vector<int> nums = {1, 2, 3, 4, 5};
int limit = 8;
// Create an object of the Solution class
Solution sol;
int ans = sol.smallestDivisor(nums, limit);
// Print the result
cout << "The minimum divisor is: " << ans << "\n";
return 0;
}
import java.util.Arrays;
class Solution {
/* Helper unction to find the
summation of division values */
private int sumByD(int[] nums, int limit) {
// Size of array
int n = nums.length;
// Find the summation of division values
int sum = 0;
for (int i = 0; i < n; i++) {
sum += Math.ceil((double)nums[i] / (double)limit);
}
return sum;
}
// Function to find the smallest divisor
public int smallestDivisor(int[] nums, int limit) {
int n = nums.length;
if (n > limit) return -1;
//Find the maximum element:
int maxi = Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
maxi = Math.max(maxi, nums[i]);
}
int low = 1, high = maxi;
// Apply binary search
while (low <= high) {
int mid = (low + high) / 2;
if (sumByD(nums, mid) <= limit) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
int limit = 8;
// Create an object of the Solution class
Solution sol = new Solution();
int ans = sol.smallestDivisor(nums, limit);
// Print the result
System.out.println("The minimum divisor is: " + ans);
}
}
import math
class Solution:
""" Helper function to find the
summation of division values"""
def sumByD(self, nums, limit):
# Size of array
n = len(nums)
# Find the summation of division values
sum_val = 0
for num in nums:
sum_val += math.ceil(num / limit)
return sum_val
# Function to find the smallest divisor
def smallestDivisor(self, nums, limit):
n = len(nums)
if n > limit:
return -1
# Initialize binary search bounds
low = 1
high = max(nums)
# Apply binary search
while low <= high:
mid = (low + high) // 2
if self.sumByD(nums, mid) <= limit:
high = mid - 1
else:
low = mid + 1
#Return the answer
return low
if __name__ == "__main__":
nums = [1, 2, 3, 4, 5]
limit = 8
# Create an object of the Solution class
sol = Solution()
ans = sol.smallestDivisor(nums, limit)
# Print the result
print(f"The minimum divisor is: {ans}")
class Solution {
/* Helper function to find the
summation of division values*/
sumByD(nums, limit) {
// Size of array
const n = nums.length;
// Find the summation of division values
let sum = 0;
for (let i = 0; i < n; i++) {
sum += Math.ceil(nums[i] / limit);
}
return sum;
}
// Function to find the smallest divisor
smallestDivisor(nums, limit) {
const n = nums.length;
if (n > limit) return -1;
// Initialize binary search bounds
let low = 1, high = Math.max(...nums);
// Apply binary search
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (this.sumByD(nums, mid) <= limit) {
high = mid - 1;
} else {
low = mid + 1;
}
}
//Return the answer
return low;
}
}
function main() {
const nums = [1, 2, 3, 4, 5];
const limit = 8;
// Create an object of the Solution class
const sol = new Solution();
const ans = sol.smallestDivisor(nums, limit);
// Print the result
console.log(`The minimum divisor is: ${ans}`);
}
main();
Q: How does the rounding work for division?
A: Instead of using ceil(nums[i]/d), compute (nums[i]+d−1)//d. This avoids floating-point arithmetic and directly calculates the rounded-up integer value.
Q: What happens if the threshold is very high?
A: If the threshold is larger than or equal to the sum of elements when divided by 1 (i.e., ∑(nums)), the smallest divisor is 1, as no larger divisor is required.
Q: What if you need the largest divisor instead of the smallest?
A: Reverse the binary search logic to prioritize larger divisors. Use the same sum calculation but adjust the bounds to find the maximum d that satisfies the condition.
Q: How would you optimize this for extremely large datasets?
A: Divide the array into chunks, calculate partial sums for each chunk, and combine them dynamically during the binary search. This reduces memory usage and ensures scalability.