Posts Allocate Books (InterviewBit)
Post
Cancel

Allocate Books (InterviewBit)

PROBLEM DESCRIPTION

Given an array of integers A of size N and an integer B.

The College library has N books. The ith book has A[i] number of pages.

You have to allocate books to B number of students so that the maximum number of pages allocated to a student is minimum.

  • A book will be allocated to exactly one student.
  • Each student has to be allocated at least one book.
  • Allotment should be in contiguous order, for example: A student cannot be allocated book 1 and book 3, skipping book 2.

Calculate and return that minimum possible number.

NOTE: Return -1 if a valid assignment is not possible.

SOLUTION

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
public class Solution {

    public int books(int[] A, int B) {

        int n = A.length; // number of books

        // Edge case:
        // If there are more students than books, each student cannot get a book
        // So we can return -1
        if(B > n) return -1;

        // We are supposed to allocate each book. Let's say the highest number of pages is MAX_PAGES. If we try with any value lower than that, we won't be able to allocate that book. So the lowest possible answer will be MAX_PAGES
        int l = A[0];

        // If there is only 1 student, he can be allocated all the pages
        // In that case the highest value possible is the sum of all pages
        int r = 0;

        // update l as MAX_PAGES and r as sum of all pages
        for(int i=0; i<n; i++){
            l = Math.max(l, A[i]);
            r += A[i];
        }

        // init ans as max possible in the range and try to minimize it using binary search
        int minPages = r;

        // Binary search to find the minimum possible number of pages that can be allocated to a student
        while(l<=r){

            int m = (l+r)/2; // Calculate the middle point

            // If it's possible to allocate books such that no student gets more than m pages
            if(isPossible(A, B, m)){

                minPages = Math.min(minPages, m); // Update the minimum possible number of pages
                r = m-1; // look for lower pages if possible
            }else{
                l = m+1; // since it's not possible, we need to try with higher number of pages
            }

        }

        return minPages;

    }

    // Method to check if it's possible to allocate books such that no student gets more than allowedPages
    public boolean isPossible(int[] A, int totalStudents, int allowedPages){

        // Number of books
        int n = A.length;

        // Number of students needed to allocate the books
        int neededStudents = 0;

        // Pages read by the current student
        int readPages = 0;

        // Iterate through each book
        for(int i=0; i<n; i++){

            // If adding pages of the current book doesn't exceed allowedPages
            if(readPages + A[i] <= allowedPages){

                // Add pages of the current book to the pages read by the current student
                readPages += A[i];

            }else{

                // Increment the count of needed students
                neededStudents++;

                // Reset the pages read by the current student to the pages of the current book
                readPages = A[i];

            }

        }

        if(readPages > 0)
            neededStudents++; // If there are remaining pages, increment the count of needed students

        // Return whether the needed students are less than or equal to totalStudents
        return neededStudents <= totalStudents;

    }

}
This post is licensed under CC BY 4.0 by the author.