Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/2355.html

2355. Maximum Number of Books You Can Take

Description

You are given a 0-indexed integer array books of length n where books[i] denotes the number of books on the ith shelf of a bookshelf.

You are going to take books from a contiguous section of the bookshelf spanning from l to r where 0 <= l <= r < n. For each index i in the range l <= i < r, you must take strictly fewer books from shelf i than shelf i + 1.

Return the maximum number of books you can take from the bookshelf.

 

Example 1:

Input: books = [8,5,2,7,9]
Output: 19
Explanation:
- Take 1 book from shelf 1.
- Take 2 books from shelf 2.
- Take 7 books from shelf 3.
- Take 9 books from shelf 4.
You have taken 19 books, so return 19.
It can be proven that 19 is the maximum number of books you can take.

Example 2:

Input: books = [7,0,3,4,5]
Output: 12
Explanation:
- Take 3 books from shelf 2.
- Take 4 books from shelf 3.
- Take 5 books from shelf 4.
You have taken 12 books so return 12.
It can be proven that 12 is the maximum number of books you can take.

Example 3:

Input: books = [8,2,3,7,3,4,0,1,4,3]
Output: 13
Explanation:
- Take 1 book from shelf 0.
- Take 2 books from shelf 1.
- Take 3 books from shelf 2.
- Take 7 books from shelf 3.
You have taken 13 books so return 13.
It can be proven that 13 is the maximum number of books you can take.

 

Constraints:

  • 1 <= books.length <= 105
  • 0 <= books[i] <= 105

Solutions

  • class Solution {
        public long maximumBooks(int[] books) {
            int n = books.length;
            int[] nums = new int[n];
            for (int i = 0; i < n; ++i) {
                nums[i] = books[i] - i;
            }
            int[] left = new int[n];
            Arrays.fill(left, -1);
            Deque<Integer> stk = new ArrayDeque<>();
            for (int i = 0; i < n; ++i) {
                while (!stk.isEmpty() && nums[stk.peek()] >= nums[i]) {
                    stk.pop();
                }
                if (!stk.isEmpty()) {
                    left[i] = stk.peek();
                }
                stk.push(i);
            }
            long ans = 0;
            long[] dp = new long[n];
            dp[0] = books[0];
            for (int i = 0; i < n; ++i) {
                int j = left[i];
                int v = books[i];
                int cnt = Math.min(v, i - j);
                int u = v - cnt + 1;
                long s = (long) (u + v) * cnt / 2;
                dp[i] = s + (j == -1 ? 0 : dp[j]);
                ans = Math.max(ans, dp[i]);
            }
            return ans;
        }
    }
    
  • using ll = long long;
    
    class Solution {
    public:
        long long maximumBooks(vector<int>& books) {
            int n = books.size();
            vector<int> nums(n);
            for (int i = 0; i < n; ++i) nums[i] = books[i] - i;
            vector<int> left(n, -1);
            stack<int> stk;
            for (int i = 0; i < n; ++i) {
                while (!stk.empty() && nums[stk.top()] >= nums[i]) stk.pop();
                if (!stk.empty()) left[i] = stk.top();
                stk.push(i);
            }
            vector<ll> dp(n);
            dp[0] = books[0];
            ll ans = 0;
            for (int i = 0; i < n; ++i) {
                int v = books[i];
                int j = left[i];
                int cnt = min(v, i - j);
                int u = v - cnt + 1;
                ll s = 1ll * (u + v) * cnt / 2;
                dp[i] = s + (j == -1 ? 0 : dp[j]);
                ans = max(ans, dp[i]);
            }
            return ans;
        }
    };
    
  • class Solution:
        def maximumBooks(self, books: List[int]) -> int:
            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)
                u = v - cnt + 1
                s = (u + v) * cnt // 2
                dp[i] = s + (0 if j == -1 else dp[j])
                ans = max(ans, dp[i])
            return ans
    
    
  • func maximumBooks(books []int) int64 {
    	n := len(books)
    	nums := make([]int, n)
    	left := make([]int, n)
    	for i, v := range books {
    		nums[i] = v - i
    		left[i] = -1
    	}
    	stk := []int{}
    	for i, v := range nums {
    		for len(stk) > 0 && nums[stk[len(stk)-1]] >= v {
    			stk = stk[:len(stk)-1]
    		}
    		if len(stk) > 0 {
    			left[i] = stk[len(stk)-1]
    		}
    		stk = append(stk, i)
    	}
    	dp := make([]int, n)
    	dp[0] = books[0]
    	ans := 0
    	for i, v := range books {
    		j := left[i]
    		cnt := min(v, i-j)
    		u := v - cnt + 1
    		s := (u + v) * cnt / 2
    		dp[i] = s
    		if j != -1 {
    			dp[i] += dp[j]
    		}
    		ans = max(ans, dp[i])
    	}
    	return int64(ans)
    }
    
    func max(a, b int) int {
    	if a > b {
    		return a
    	}
    	return b
    }
    
    func min(a, b int) int {
    	if a < b {
    		return a
    	}
    	return b
    }
    

All Problems

All Solutions