This problem involves finding the maximum number of books you can take from a contiguous section of shelves, with the constraint that the number of books taken from each shelf must be strictly less than the number taken from the next shelf. This constraint immediately suggests a dynamic programming (DP) approach or a monotonic stack approach to efficiently find the optimal solution. The solution presented below utilizes a monotonic stack to optimize the DP process.
Understanding the Problem:
The core challenge lies in efficiently finding the best contiguous section and the optimal number of books to take from each shelf within that section, satisfying the increasing sequence constraint. A brute-force approach would explore all possible contiguous sections and book selections, leading to exponential time complexity.
Monotonic Stack and DP Approach:
The solution leverages a monotonic decreasing stack to precompute information useful for the DP step.
Difference Array: We first create a difference array nums
where nums[i] = books[i] - i
. This transformation helps simplify the increasing sequence constraint. If we take k
books from shelf i
, we must take k+1
from shelf i+1
, k+2
from shelf i+2
, and so on. The difference array ensures the increasing number of books condition is easier to check. If we select a range where we pick books in strictly increasing numbers, the values in the difference array will be monotonically non-increasing.
Monotonic Stack (Finding Left Boundaries): A monotonic decreasing stack stk
is used to efficiently find the leftmost index left[i]
such that nums[left[i]] >= nums[i]
. This left[i]
represents the left boundary for a potential contiguous selection ending at index i
. If nums[j] < nums[i]
for all j < i, then left[i]
is -1, signifying no such boundary exists to the left.
Dynamic Programming: A DP array dp
stores the maximum number of books that can be taken considering shelves up to index i
. The recurrence relation is:
dp[i] = max(dp[i], s + (j == -1 ? 0 : dp[j]))
where s
is the total number of books taken in the contiguous section ending at index i
(calculated using a simple arithmetic series formula), and j
is left[i]
.
Maximum Books: The final answer is the maximum value in the dp
array.
Time and Space Complexity:
books
). The monotonic stack and DP iterations each take linear time.nums
, left
, and dp
arrays.Code (Python):
def maximumBooks(books):
nums = [v - i for i, v in enumerate(books)]
n = len(nums)
left = [-1] * n
stk = []
for i, v in enumerate(nums):
while stk and nums[stk[-1]] >= v:
stk.pop()
if stk:
left[i] = stk[-1]
stk.append(i)
ans = 0
dp = [0] * n
dp[0] = books[0]
for i, v in enumerate(books):
j = left[i]
cnt = min(v, i - j) #Number of shelves in current sequence
u = v - cnt + 1 #First number in arithmetic series
s = (u + v) * cnt // 2 #Sum of arithmetic series
dp[i] = s + (0 if j == -1 else dp[j])
ans = max(ans, dp[i])
return ans
The other languages (Java, C++, Go) follow a similar structure, adapting the syntax and data structures to their respective languages. The core algorithm remains the same: monotonic stack preprocessing followed by dynamic programming for optimal solution calculation.