
LeetCode 1283 β Find the Smallest Divisor Given a Threshold | Binary Search on Answer Explained
π Try This Problem First!Before reading the solution, attempt it yourself on LeetCode β you'll retain the concept far better.π Problem Link: https://leetcode.com/problems/find-the-smallest-divisor-given-a-threshold/Understanding the ProblemYou are given an array of integers nums and an integer threshold. You must choose a positive integer divisor, divide every element of the array by it (rounding up to the nearest integer), sum all the results, and make sure that sum is β€ threshold.Goal: Find the smallest possible divisor that keeps the sum within the threshold.Important detail β Ceiling Division: Every division rounds up, not down. So 7 Γ· 3 = 3 (not 2), and 10 Γ· 2 = 5.Constraints:1 β€ nums.length β€ 5 Γ 10β΄1 β€ nums[i] β€ 10βΆnums.length β€ threshold β€ 10βΆTwo Key Observations (Before Writing a Single Line of Code)Minimum possible divisor: The divisor must be at least 1. Dividing by anything less than 1 isn't a positive integer. So:low = 1Maximum possible divisor: If divisor = max(nums), then every element divided by it gives at most 1 (due to ceiling), so the sum equals nums.length, which is always β€ threshold (guaranteed by constraints). So:high = max(nums)Our answer lies in the range [1, max(nums)]. This is the search space for Binary Search.Intuition β Why Binary Search?Ask yourself: what happens as the divisor increases?As divisor gets larger, each divided value gets smaller (or stays the same), so the total sum decreases or stays the same. This is a monotonic relationship β the green flag for Binary Search on the Answer.Instead of trying every divisor from 1 to max(nums), we binary search over divisor values. For each candidate mid, we ask:"Does dividing all elements by mid (ceiling) give a sum β€ threshold?"This feasibility check runs in O(N), making the whole approach O(N log(max(nums))).The Feasibility Check β Ceiling Sum SimulationGiven a divisor mid, compute the sum of βarr[i] / midβ for all elements. If the total sum β€ threshold, then mid is a valid divisor.In Java, ceiling division of integers is done as:Math.ceil((double) arr[i] / mid)Binary Search StrategyIf canDivide(mid) is true β mid might be the answer, but try smaller. Set ans = mid, high = mid - 1.If canDivide(mid) is false β divisor is too small, increase it. Set low = mid + 1.Dry Run β Example 1 (Step by Step)Input: nums = [1, 2, 5, 9], threshold = 6We start with low = 1 and high = 9 (max element in array).Iteration 1: mid = 1 + (9 - 1) / 2 = 5Compute ceiling sum with divisor 5: β1/5β + β2/5β + β5/5β + β9/5β = 1 + 1 + 1 + 2 = 55 β€ 6 β β Valid. Record ans = 5, search smaller β high = 4.Iteration 2: mid = 1 + (4 - 1) / 2 = 2Compute ceiling sum with divisor 2: β1/2β + β2/2β + β5/2β + β9/2β = 1 + 1 + 3 + 5 = 1010 > 6 β β Too large. Increase divisor β low = 3.Iteration 3: mid = 3 + (4 - 3) / 2 = 3Compute ceiling sum with divisor 3: β1/3β + β2/3β + β5/3β + β9/3β = 1 + 1 + 2 + 3 = 77 > 6 β β Too large. Increase divisor β low = 4.Iteration 4: mid = 4 + (4 - 4) / 2 = 4Compute ceiling sum with divisor 4: β1/4β + β2/4β + β5/4β + β9/4β = 1 + 1 + 2 + 3 = 77 > 6 β β Too large. Increase divisor β low = 5.Loop ends: low (5) > high (4). Binary search terminates.Output: ans = 5 β The Code Implementationclass Solution {/*** Feasibility Check (Helper Function)** Given a divisor 'mid', this function computes the ceiling sum of* all elements divided by 'mid' and checks if it is within threshold.** @param mid - candidate divisor to test* @param arr - input array* @param thresh - the allowed threshold for the sum* @return true if the ceiling division sum <= threshold, false otherwise*/public boolean canDivide(int mid, int[] arr, int thresh) {int sumOfDiv = 0;for (int i = 0; i < arr.length; i++) {// Ceiling division: Math.ceil(arr[i] / mid)// Cast to double to avoid integer division truncationsumOfDiv += Math.ceil((double) arr[i] / mid);}// If total sum is within threshold, this divisor is validreturn sumOfDiv <= thresh;}/*** Main Function β Binary Search on the Answer** Search range: [1, max(nums)]* - low = 1 β smallest valid positive divisor* - high = max(nums) β guarantees every ceil(num/divisor) = 1,* so sum = nums.length <= threshold (always valid)** @param nums - input array* @param threshold - maximum allowed sum after ceiling division* @return smallest divisor such that the ceiling division sum <= threshold*/public int smallestDivisor(int[] nums, int threshold) {int min = 1; // Lower bound: divisor starts at 1int max = Integer.MIN_VALUE; // Will become max(nums)int ans = 1;// Find the upper bound of binary search (max element)for (int a : nums) {max = Math.max(max, a);}// Binary Search over the divisor spacewhile (min <= max) {int mid = min + (max - min) / 2; // Safe midpoint, avoids overflowif (canDivide(mid, nums, threshold)) {// mid is valid β record it and try a smaller divisorans = mid;max = mid - 1;} else {// mid is too small β the sum exceeded threshold, go highermin = mid + 1;}}return ans; // Smallest valid divisor}}Code Walkthrough β Step by StepSetting bounds: We iterate through nums once to find max β this becomes our upper bound high. The lower bound low = 1 because divisors must be positive integers.Binary Search loop: We pick mid = min + (max - min) / 2 as the candidate divisor. We check if using mid as the divisor keeps the ceiling sum β€ threshold.Feasibility helper (canDivide): For each element, we compute Math.ceil((double) arr[i] / mid) and accumulate the total. The cast to double is critical β without it, Java performs integer division (which truncates, not rounds up).Narrowing the search: If the sum is within threshold β record ans = mid, try smaller (max = mid - 1). If the sum exceeds threshold β divisor is too small, increase it (min = mid + 1).A Critical Bug to Watch Out For β The return min vs return ans TrapIn your original code, the final line was return min instead of return ans. This is a subtle bug. After the loop ends, min has overshot past the answer (it's now ans + 1). Always store the answer in a dedicated variable ans and return that. Using return min would return the wrong result in most cases.Common Mistakes to AvoidWrong lower bound: Setting low = min(nums) instead of low = 1 seems intuitive but is wrong. A divisor smaller than the minimum element is still valid β for example, dividing [5, 9] by 3 gives β5/3β + β9/3β = 2 + 3 = 5, which could be within threshold.Forgetting ceiling division: Using arr[i] / mid (integer division, which truncates) instead of Math.ceil((double) arr[i] / mid) is wrong. The problem explicitly states results are rounded up.Returning min instead of ans: After the binary search loop ends, min > max, meaning min has already gone past the valid answer. Always return the stored ans.Integer overflow in midpoint: Always use mid = min + (max - min) / 2 instead of (min + max) / 2. When both values are large (up to 10βΆ), their sum can overflow an int.Complexity AnalysisTime Complexity: O(N Γ log(max(nums)))Binary search runs over [1, max(nums)] β at most logβ(10βΆ) β 20 iterations.Each iteration calls canDivide which is O(N).Total: O(N log M) where M = max(nums).Space Complexity: O(1) No extra data structures β only a few integer variables are used throughout.How This Relates to LeetCode 1011This problem and LeetCode 1011 (Ship Packages Within D Days) are almost identical in structure:π LeetCode 1011 #Search space: [max(weights), sum(weights)]Feasibility check: Can we ship in β€ D days?Monotonic property: More capacity β fewer daysGoal: Minimize capacityLeetCode 1283Search space: [1, max(nums)]Feasibility check: Is ceiling sum β€ threshold?Monotonic property: Larger divisor β smaller sumGoal: Minimize divisorOnce you deeply understand one, the other takes minutes to solve.Similar Problems (Same Pattern β Binary Search on Answer)LeetCode 875 β Koko Eating Bananas [ Blog is also avaliable on this - Read Now ]LeetCode 1011 β Capacity To Ship Packages Within D Days [ Blog is also avaliable on this - Read Now ]LeetCode 410 β Split Array Largest SumLeetCode 2064 β Minimized Maximum of Products Distributed to Any StoreAll follow the same template: identify a monotonic answer space, write an O(N) feasibility check, and binary search over it.Key Takeawaysβ When the problem asks "find the minimum value such that a condition holds" β think Binary Search on the Answer.β The lower bound is the most constrained valid value (1 here, since divisors must be positive).β The upper bound is the least constrained valid value (max element, guarantees sum = length β€ threshold).β Ceiling division in Java requires casting to double: Math.ceil((double) a / b).β Always store the answer in a separate ans variable β never return min or max directly after a binary search loop.Happy Coding! Smash that upvote if this helped you crack the pattern. π
