githubEdit

15. Smallest Divisor

โœ… GFG solution to the Smallest Divisor problem: find the smallest divisor such that sum of ceiling divisions is โ‰ค k using binary search. ๐Ÿš€

The problem can be found at the following link: ๐Ÿ”— Question Linkarrow-up-right

๐Ÿงฉ Problem Description

Given an integer array arr[] and an integer k (where k โ‰ฅ arr.length), find the smallest positive integer divisor such that the sum of the ceiling values of each element in arr[] divided by this divisor is less than or equal to k.

For a divisor d, the sum is calculated as: โŒˆarr[0]/dโŒ‰ + โŒˆarr[1]/dโŒ‰ + ... + โŒˆarr[n-1]/dโŒ‰ โ‰ค k

๐Ÿ“˜ Examples

Example 1

Input: arr[] = [1, 2, 5, 9], k = 6
Output: 5
Explanation: 5 is the smallest divisor having sum of quotients:
โŒˆ1/5โŒ‰ + โŒˆ2/5โŒ‰ + โŒˆ5/5โŒ‰ + โŒˆ9/5โŒ‰ = 1 + 1 + 1 + 2 = 5 โ‰ค 6

Example 2

Input: arr[] = [1, 1, 1, 1], k = 4
Output: 1
Explanation: 1 is the smallest divisor having sum of quotients:
โŒˆ1/1โŒ‰ + โŒˆ1/1โŒ‰ + โŒˆ1/1โŒ‰ + โŒˆ1/1โŒ‰ = 1 + 1 + 1 + 1 = 4 โ‰ค 4

๐Ÿ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^5$

  • $1 \le \text{arr}[i] \le 10^6$

  • $\text{arr.size()} \le k \le 10^6$

โœ… My Approach

The optimal approach uses Binary Search on the answer space. Since we need the smallest divisor, we can search in the range [1, max(arr)]:

  1. Define Search Space:

    • Lower bound: l = 1 (smallest positive divisor)

    • Upper bound: h = max(arr) (largest possible needed divisor)

  2. Binary Search Logic:

    • For each mid value m, calculate the sum of ceiling divisions

    • Use the formula: โŒˆa/bโŒ‰ = (a + b - 1) / b for efficient ceiling calculation

    • If sum โ‰ค k, try smaller divisors (move right boundary)

    • If sum > k, need larger divisors (move left boundary)

  3. Ceiling Division Optimization:

    • Instead of using ceil(arr[i]/m), use (arr[i] + m - 1) / m

    • This avoids floating-point operations and is more efficient

  4. Termination:

    • When l >= h, we found the smallest valid divisor

๐Ÿ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n * log(max_element)), where n is the array size. Binary search runs in O(log(max_element)) iterations, and each iteration requires O(n) time to calculate the sum of ceiling divisions.

  • Expected Auxiliary Space Complexity: O(1), as we only use constant extra space for variables like left, right, mid, and sum.

๐Ÿง‘โ€๐Ÿ’ป Code (C++)

chevron-rightโšก View Alternative Approaches with Code and Analysishashtag

๐Ÿ“Š 2๏ธโƒฃ Binary Search with Math Ceiling

๐Ÿ’ก Algorithm Steps:

  1. Use mathematical ceiling function for division.

  2. Standard binary search template.

  3. Explicit ceiling calculation.

๐Ÿ“ Complexity Analysis:

  • Time: โฑ๏ธ O(n * log(max_element))

  • Auxiliary Space: ๐Ÿ’พ O(1)

โœ… Why This Approach?

  • More readable ceiling division logic.

  • Classical binary search pattern.

๐Ÿ“Š 3๏ธโƒฃ Ternary Search Approach

๐Ÿ’ก Algorithm Steps:

  1. Divide search space into three parts instead of two.

  2. Compare function values at two mid points.

  3. Eliminate one-third of search space each iteration.

๐Ÿ“ Complexity Analysis:

  • Time: โฑ๏ธ O(n * logโ‚ƒ(max_element))

  • Auxiliary Space: ๐Ÿ’พ O(1)

โœ… Why This Approach?

  • Theoretically faster convergence than binary search.

  • Reduces search space by 1/3 each iteration.

๐Ÿ“Š 4๏ธโƒฃ Square Root Decomposition

๐Ÿ’ก Algorithm Steps:

  1. Divide array into โˆšn blocks.

  2. Precompute partial sums for blocks.

  3. Use binary search with block-wise calculation.

๐Ÿ“ Complexity Analysis:

  • Time: โฑ๏ธ O(n * log(max_element))

  • Auxiliary Space: ๐Ÿ’พ O(n)

โœ… Why This Approach?

  • Better cache locality for large arrays.

  • Potential for parallelization.

๐Ÿ†š ๐Ÿ” Comparison of Approaches

๐Ÿš€ Approach

โฑ๏ธ Time Complexity

๐Ÿ’พ Space Complexity

โœ… Pros

โš ๏ธ Cons

๐Ÿ” Binary Search(Ultra-Optimized)

๐ŸŸข O(n * log(max))

๐ŸŸข O(1)

โšก Fastest runtime, minimal ops

๐Ÿงฎ Less readable

๐Ÿ”„ Math Ceiling

๐ŸŸข O(n * log(max))

๐ŸŸข O(1)

๐Ÿ”ง Clear division logic

๐Ÿข More operations per iteration

๐Ÿ”บ Ternary Search

๐ŸŸข O(n * logโ‚ƒ(max))

๐ŸŸข O(1)

๐Ÿš€ Faster theoretical convergence

๐Ÿงฎ Complex implementation

๐Ÿ“Š Sqrt Decomposition

๐ŸŸข O(n * log(max))

๐Ÿ”ธ O(n)

๐ŸŽ๏ธ Better cache locality

๐Ÿ’พ Extra space overhead

๐Ÿ† Best Choice Recommendation

๐ŸŽฏ Scenario

๐ŸŽ–๏ธ Recommended Approach

๐Ÿ”ฅ Performance Rating

โšก Maximum performance, large datasets

๐Ÿฅ‡ Binary Search

โ˜…โ˜…โ˜…โ˜…โ˜…

๐Ÿ”ง Code clarity with good performance

๐Ÿฅˆ Math Ceiling

โ˜…โ˜…โ˜…โ˜…โ˜†

๐Ÿ“Š Theoretical optimization

๐Ÿฅ‰ Ternary Search

โ˜…โ˜…โ˜…โ˜…โ˜†

๐ŸŽ๏ธ Cache-sensitive large arrays

๐Ÿ… Sqrt Decomposition

โ˜…โ˜…โ˜…โ˜†โ˜†

๐Ÿง‘โ€๐Ÿ’ป Code (Java)

๐Ÿ Code (Python)

๐Ÿง  Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐Ÿ“ฌ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

โญ If you find this helpful, please give this repository a star! โญ


๐Ÿ“Visitor Count

Visitor counter

Last updated