Allocate Minimum Pages
JavaView on GFG
Advertisement
Intuition
Binary search on the answer (minimum of maximum pages). For a given mid, check if we can allocate books to m students such that each student gets at most mid pages.
Algorithm
- 1lo = max(books), hi = sum(books).
- 2Binary search: mid = (lo+hi)/2. Check feasibility: greedily assign books; if a student would exceed mid, start a new student.
- 3If feasible with ≤ m students: hi=mid. Else lo=mid+1.
- 4Return lo.
Example Walkthrough
Input: books=[12,34,67,90], m=2
- 1.lo=90, hi=203. mid=146: [12,34,67] to student1 (113≤146), [90] to student2 → 2 students ✓.
- 2.hi=146. mid=118: [12,34,67] (113≤118), [90] ✓. hi=118.
- 3.Continue until lo=hi=113.
Output: 113
Common Pitfalls
- •A student must get at least one book. Books must be contiguous (can't reorder).
Allocate Minimum Pages.java
Java
// Approach: Binary search on the answer (max pages allocated to a student).
// For each mid value, greedily count how many students are needed; adjust search range.
// Time: O(n log(sum)) Space: O(1)
class Solution {
public static int findPages(int[] arr, int k) {
int n = arr.length;
// If there are more students than books, it's not possible
if (n < k)
return -1;
// Initialize low and high for binary search
int low = 0;
int high = 0;
// Calculate the sum of pages and max pages in a book
for (int i = 0; i < n; i++) {
high += arr[i];
low = Math.max(low, arr[i]); // Max pages in a single book
}
// Binary search to find the minimum possible maximum pages a student can have
while (low < high) {
int mid = low + (high - low) / 2;
// Check if it's possible to allocate books with `mid` as the maximum pages
if (isPossible(arr, k, mid))
high = mid; // Try to find a smaller maximum
else
low = mid + 1; // Increase the minimum pages
}
// The answer will be in `low` as it's the smallest maximum possible
return low;
}
// Helper function to check if it's possible to allocate books with max
// `maxPages`
private static boolean isPossible(int[] arr, int k, int maxPages) {
int students = 1; // Start with the first student
int currentSum = 0;
for (int i = 0; i < arr.length; i++) {
// If adding the current book exceeds maxPages, assign it to the next student
if (currentSum + arr[i] > maxPages) {
students++;
currentSum = arr[i];
// If there are more students than allowed, return false
if (students > k)
return false;
} else
currentSum += arr[i];
}
return true;
}
}
class Solution1 {
public int findPages(int[] arr, int k) {
int n = arr.length;
if (k > n)
return -1;
int low = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > low)
low = arr[i];
}
int high = 0;
for (int i = 0; i < n; i++)
high += arr[i];
while (low <= high) {
int mid = (low + high) / 2;
if (countStudent(arr, mid) > k)
low = mid + 1;
else
high = mid - 1;
}
return low;
}
public int countStudent(int[] arr, int pages) {
int n = arr.length;
int student = 1;
long studentPages = 0;
for (int i = 0; i < n; i++) {
if (studentPages + arr[i] <= pages)
studentPages += arr[i];
else {
student++;
studentPages = arr[i];
}
}
return student;
}
}Advertisement
Was this solution helpful?