2281. Sum of Total Strength of Wizards
Problem Description
You are given an array strength
where strength[i]
represents the strength of the i-th wizard in your kingdom.
For any contiguous subarray of wizards, the total strength is calculated as:
- The minimum strength among all wizards in the subarray
- Multiplied by the sum of all strengths in the subarray
For example, if you have a subarray [3, 1, 5]
:
- The weakest wizard has strength
1
- The sum of all strengths is
3 + 1 + 5 = 9
- The total strength is
1 × 9 = 9
Your task is to find the sum of total strengths for all possible contiguous subarrays in the given array.
Since the result can be very large, return the answer modulo 10^9 + 7
.
Example walkthrough:
If strength = [1, 3, 2]
, the contiguous subarrays and their total strengths are:
[1]
: min = 1, sum = 1, total strength = 1 × 1 = 1[3]
: min = 3, sum = 3, total strength = 3 × 3 = 9[2]
: min = 2, sum = 2, total strength = 2 × 2 = 4[1, 3]
: min = 1, sum = 4, total strength = 1 × 4 = 4[3, 2]
: min = 2, sum = 5, total strength = 2 × 5 = 10[1, 3, 2]
: min = 1, sum = 6, total strength = 1 × 6 = 6
The sum of all total strengths = 1 + 9 + 4 + 4 + 10 + 6 = 34
Intuition
The brute force approach would be to check every possible subarray, find its minimum element and sum, then calculate the total strength. This would take O(n^3)
time, which is too slow for large arrays.
The key insight is to think about the problem from a different angle: instead of iterating through all subarrays, we can focus on each element and ask - "In how many subarrays is this element the minimum?"
For each element strength[i]
, if we know all the subarrays where it acts as the minimum element, we can calculate its contribution to the final answer. The contribution would be:
strength[i] × (sum of all subarray sums where strength[i] is the minimum)
To find which subarrays have strength[i]
as their minimum, we need to find:
- The nearest smaller element to the left (let's call its index
left[i]
) - The nearest smaller or equal element to the right (let's call its index
right[i]
)
Any subarray that includes strength[i]
and spans from index l
(where left[i] < l <= i
) to index r
(where i <= r < right[i]
) will have strength[i]
as its minimum element.
The next challenge is efficiently calculating the sum of all subarray sums that include strength[i]
as the minimum. This is where prefix sums come in handy. By using a double prefix sum (prefix sum of prefix sums), we can calculate in O(1)
time:
- The sum of all subarray sums that start from any position between
left[i]+1
toi
and end at any position betweeni
toright[i]-1
The monotonic stack technique helps us efficiently find the nearest smaller elements on both sides in O(n)
time. We use the stack to maintain elements in increasing order, popping elements when we find a smaller one.
This approach reduces the overall time complexity to O(n)
, making it efficient even for large arrays.
Learn more about Stack, Prefix Sum and Monotonic Stack patterns.
Solution Approach
The solution implements the intuition using monotonic stacks and prefix sums. Let's walk through each component:
Step 1: Find boundaries using monotonic stacks
First, we find for each element the range where it acts as the minimum:
left = [-1] * n # nearest smaller element to the left right = [n] * n # nearest smaller or equal element to the right
For the left boundaries:
- Iterate through the array from left to right
- Maintain a stack of indices in increasing order of their values
- When we encounter
strength[i]
, pop all elements from the stack that are>= strength[i]
- The top of the stack (if exists) gives us
left[i]
For the right boundaries:
- Iterate through the array from right to left
- Similar process, but we pop elements that are
> strength[i]
(strictly greater) - This ensures we handle equal elements correctly (leftmost one is chosen as minimum)
Step 2: Calculate prefix sums of prefix sums
ss = list(accumulate(list(accumulate(strength, initial=0)), initial=0))
This creates a double prefix sum array where:
- First
accumulate
gives us regular prefix sums:ps[i] = strength[0] + ... + strength[i-1]
- Second
accumulate
gives us prefix sums of prefix sums:ss[i] = ps[0] + ps[1] + ... + ps[i-1]
Step 3: Calculate contribution of each element
For each element at index i
with value v
:
- It's the minimum in all subarrays from
[l, r]
wherel ∈ [left[i]+1, i]
andr ∈ [i, right[i]-1]
The sum of all subarray sums where strength[i]
is minimum can be calculated as:
a = (ss[r + 2] - ss[i + 1]) * (i - l + 1) # sum of subarrays ending after i b = (ss[i + 1] - ss[l]) * (r - i + 1) # sum of subarrays starting before i total_sum = a - b
This formula uses the double prefix sum to efficiently compute:
a
: Sum of all subarrays that end at positions fromi
tor
, multiplied by the number of possible starting positionsb
: Sum of all subarrays that start at positions froml
toi
, multiplied by the number of possible ending positions
The contribution of element i
is then: (a - b) * v
Step 4: Sum all contributions
ans = (ans + (a - b) * v) % mod
We add each element's contribution to the final answer, taking modulo at each step to prevent overflow.
The time complexity is O(n)
as we make a constant number of passes through the array, and space complexity is O(n)
for the auxiliary arrays.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution approach with strength = [2, 1, 3]
.
Step 1: Find boundaries using monotonic stacks
Finding left[]
(nearest smaller element to the left):
- i=0, strength[0]=2: stack is empty, so left[0]=-1. Push 0 to stack. Stack: [0]
- i=1, strength[1]=1: Pop 0 (since 2≥1). Stack empty, so left[1]=-1. Push 1. Stack: [1]
- i=2, strength[2]=3: 1<3, so left[2]=1. Push 2. Stack: [1,2]
- Result:
left = [-1, -1, 1]
Finding right[]
(nearest smaller or equal to the right):
- i=2, strength[2]=3: stack empty, so right[2]=3. Push 2. Stack: [2]
- i=1, strength[1]=1: Pop 2 (since 3>1). Stack empty, so right[1]=3. Push 1. Stack: [1]
- i=0, strength[0]=2: 1<2, so right[0]=1. Push 0. Stack: [1,0]
- Result:
right = [1, 3, 3]
Step 2: Calculate prefix sums of prefix sums
- Original:
[2, 1, 3]
- First prefix sum:
[0, 2, 3, 6]
(ps[i] = sum of elements before index i) - Second prefix sum:
[0, 0, 2, 5, 11]
(ss[i] = sum of ps[0] to ps[i-1])
Step 3: Calculate contribution of each element
For element at index 0 (value=2):
- It's minimum in subarrays from [l=0, r=0] (since left[0]=-1, right[0]=1)
- l = left[0]+1 = 0, r = right[0]-1 = 0
- a = (ss[0+2] - ss[0+1]) × (0-0+1) = (2-0) × 1 = 2
- b = (ss[0+1] - ss[0]) × (0-0+1) = (0-0) × 1 = 0
- Contribution = (2-0) × 2 = 4
For element at index 1 (value=1):
- It's minimum in subarrays from [l=0, r=2] (since left[1]=-1, right[1]=3)
- l = left[1]+1 = 0, r = right[1]-1 = 2
- a = (ss[2+2] - ss[1+1]) × (1-0+1) = (11-2) × 2 = 18
- b = (ss[1+1] - ss[0]) × (2-1+1) = (2-0) × 2 = 4
- Contribution = (18-4) × 1 = 14
For element at index 2 (value=3):
- It's minimum in subarrays from [l=2, r=2] (since left[2]=1, right[2]=3)
- l = left[2]+1 = 2, r = right[2]-1 = 2
- a = (ss[2+2] - ss[2+1]) × (2-2+1) = (11-5) × 1 = 6
- b = (ss[2+1] - ss[2]) × (2-2+1) = (5-2) × 1 = 3
- Contribution = (6-3) × 3 = 9
Step 4: Sum all contributions Total = 4 + 14 + 9 = 27
Let's verify:
- [2]: min=2, sum=2, strength=2×2=4 ✓
- [1]: min=1, sum=1, strength=1×1=1
- [3]: min=3, sum=3, strength=3×3=9 ✓
- [2,1]: min=1, sum=3, strength=1×3=3
- [1,3]: min=1, sum=4, strength=1×4=4
- [2,1,3]: min=1, sum=6, strength=1×6=6
Total = 4+1+9+3+4+6 = 27 ✓
Solution Implementation
1class Solution:
2 def totalStrength(self, strength: List[int]) -> int:
3 """
4 Calculate the sum of total strength across all subarrays.
5 For each subarray, total strength = min(subarray) * sum(subarray)
6 """
7 n = len(strength)
8
9 # Find the previous smaller element for each position
10 # left[i] = index of the nearest element to the left that is strictly smaller than strength[i]
11 # -1 if no such element exists
12 left_smaller = [-1] * n
13 stack = []
14
15 for i, current_strength in enumerate(strength):
16 # Pop elements that are greater than or equal to current
17 while stack and strength[stack[-1]] >= current_strength:
18 stack.pop()
19
20 if stack:
21 left_smaller[i] = stack[-1]
22 stack.append(i)
23
24 # Find the next smaller or equal element for each position
25 # right[i] = index of the nearest element to the right that is smaller than or equal to strength[i]
26 # n if no such element exists
27 right_smaller = [n] * n
28 stack = []
29
30 for i in range(n - 1, -1, -1):
31 # Pop elements that are strictly greater than current
32 while stack and strength[stack[-1]] > strength[i]:
33 stack.pop()
34
35 if stack:
36 right_smaller[i] = stack[-1]
37 stack.append(i)
38
39 # Build prefix sum array and prefix sum of prefix sums
40 # This helps calculate range sums efficiently
41 # prefix_sum_of_prefix_sums[i] = sum of all prefix sums up to index i-1
42 prefix_sum_of_prefix_sums = list(accumulate(list(accumulate(strength, initial=0)), initial=0))
43
44 MOD = 10**9 + 7
45 total_strength_sum = 0
46
47 # For each element as the minimum of subarrays
48 for i, min_strength in enumerate(strength):
49 # Range where strength[i] is the minimum
50 # All subarrays from index left_bound to right_bound that include i
51 left_bound = left_smaller[i] + 1
52 right_bound = right_smaller[i] - 1
53
54 # Calculate contribution of all subarrays where strength[i] is minimum
55 # Using the formula for sum of subarray sums
56
57 # Sum of all subarrays ending after i and starting at or before i
58 positive_contribution = (prefix_sum_of_prefix_sums[right_bound + 2] - prefix_sum_of_prefix_sums[i + 1]) * (i - left_bound + 1)
59
60 # Sum of all subarrays starting before i and ending at or before i
61 negative_contribution = (prefix_sum_of_prefix_sums[i + 1] - prefix_sum_of_prefix_sums[left_bound]) * (right_bound - i + 1)
62
63 # Add the contribution of this element as minimum
64 contribution = (positive_contribution - negative_contribution) * min_strength
65 total_strength_sum = (total_strength_sum + contribution) % MOD
66
67 return total_strength_sum
68
1class Solution {
2 public int totalStrength(int[] strength) {
3 int n = strength.length;
4
5 // Find the previous smaller element for each position
6 // leftBoundary[i] = index of the previous element < strength[i], or -1 if none exists
7 int[] leftBoundary = new int[n];
8 Arrays.fill(leftBoundary, -1);
9
10 // Find the next smaller or equal element for each position
11 // rightBoundary[i] = index of the next element <= strength[i], or n if none exists
12 int[] rightBoundary = new int[n];
13 Arrays.fill(rightBoundary, n);
14
15 // Use monotonic stack to find previous smaller elements
16 Deque<Integer> monotonicStack = new ArrayDeque<>();
17 for (int i = 0; i < n; ++i) {
18 // Pop elements that are greater than or equal to current element
19 while (!monotonicStack.isEmpty() && strength[monotonicStack.peek()] >= strength[i]) {
20 monotonicStack.pop();
21 }
22 // The remaining top element (if exists) is the previous smaller element
23 if (!monotonicStack.isEmpty()) {
24 leftBoundary[i] = monotonicStack.peek();
25 }
26 monotonicStack.push(i);
27 }
28
29 // Clear stack for reuse
30 monotonicStack.clear();
31
32 // Use monotonic stack to find next smaller or equal elements (traverse from right)
33 for (int i = n - 1; i >= 0; --i) {
34 // Pop elements that are strictly greater than current element
35 while (!monotonicStack.isEmpty() && strength[monotonicStack.peek()] > strength[i]) {
36 monotonicStack.pop();
37 }
38 // The remaining top element (if exists) is the next smaller or equal element
39 if (!monotonicStack.isEmpty()) {
40 rightBoundary[i] = monotonicStack.peek();
41 }
42 monotonicStack.push(i);
43 }
44
45 // Define modulo for avoiding overflow
46 int MOD = (int) 1e9 + 7;
47
48 // Build prefix sum array
49 // prefixSum[i] = sum of strength[0] to strength[i-1]
50 int[] prefixSum = new int[n + 1];
51 for (int i = 0; i < n; ++i) {
52 prefixSum[i + 1] = (prefixSum[i] + strength[i]) % MOD;
53 }
54
55 // Build prefix sum of prefix sums
56 // prefixSumOfSums[i] = sum of prefixSum[0] to prefixSum[i-1]
57 int[] prefixSumOfSums = new int[n + 2];
58 for (int i = 0; i < n + 1; ++i) {
59 prefixSumOfSums[i + 1] = (prefixSumOfSums[i] + prefixSum[i]) % MOD;
60 }
61
62 // Calculate the total strength
63 long totalResult = 0;
64
65 for (int i = 0; i < n; ++i) {
66 int currentValue = strength[i];
67 // Range where strength[i] is the minimum element
68 int leftIndex = leftBoundary[i] + 1;
69 int rightIndex = rightBoundary[i] - 1;
70
71 // Calculate contribution of all subarrays where strength[i] is minimum
72 // For subarrays ending at or after i
73 long rightContribution = (long) (i - leftIndex + 1) * (prefixSumOfSums[rightIndex + 2] - prefixSumOfSums[i + 1]);
74 // For subarrays ending before i
75 long leftContribution = (long) (rightIndex - i + 1) * (prefixSumOfSums[i + 1] - prefixSumOfSums[leftIndex]);
76
77 // Add the contribution of current element as minimum
78 totalResult = (totalResult + currentValue * ((rightContribution - leftContribution) % MOD)) % MOD;
79 }
80
81 // Handle negative modulo result
82 return (int) (totalResult + MOD) % MOD;
83 }
84}
85
1class Solution {
2public:
3 int totalStrength(vector<int>& strength) {
4 int n = strength.size();
5 const int MOD = 1e9 + 7;
6
7 // Find the previous smaller element for each position
8 // leftBound[i] = index of the previous element smaller than strength[i]
9 vector<int> leftBound(n, -1);
10 stack<int> monoStack;
11
12 for (int i = 0; i < n; ++i) {
13 // Pop elements that are greater than or equal to current element
14 while (!monoStack.empty() && strength[monoStack.top()] >= strength[i]) {
15 monoStack.pop();
16 }
17 if (!monoStack.empty()) {
18 leftBound[i] = monoStack.top();
19 }
20 monoStack.push(i);
21 }
22
23 // Find the next smaller or equal element for each position
24 // rightBound[i] = index of the next element smaller or equal to strength[i]
25 vector<int> rightBound(n, n);
26 monoStack = stack<int>(); // Reset the stack
27
28 for (int i = n - 1; i >= 0; --i) {
29 // Pop elements that are strictly greater than current element
30 while (!monoStack.empty() && strength[monoStack.top()] > strength[i]) {
31 monoStack.pop();
32 }
33 if (!monoStack.empty()) {
34 rightBound[i] = monoStack.top();
35 }
36 monoStack.push(i);
37 }
38
39 // Build prefix sum array: prefixSum[i+1] = sum of strength[0..i]
40 vector<int> prefixSum(n + 1, 0);
41 for (int i = 0; i < n; ++i) {
42 prefixSum[i + 1] = (prefixSum[i] + strength[i]) % MOD;
43 }
44
45 // Build prefix sum of prefix sums: prefixSumOfSums[i+1] = sum of prefixSum[0..i]
46 vector<int> prefixSumOfSums(n + 2, 0);
47 for (int i = 0; i <= n; ++i) {
48 prefixSumOfSums[i + 1] = (prefixSumOfSums[i] + prefixSum[i]) % MOD;
49 }
50
51 // Calculate the total strength
52 int totalResult = 0;
53
54 for (int i = 0; i < n; ++i) {
55 int minValue = strength[i];
56 int leftIdx = leftBound[i] + 1; // Left boundary of subarrays where strength[i] is minimum
57 int rightIdx = rightBound[i] - 1; // Right boundary of subarrays where strength[i] is minimum
58
59 // Calculate contribution of all subarrays where strength[i] is the minimum
60 // leftContribution: sum of all subarrays ending at or after position i
61 long leftContribution = (long)(i - leftIdx + 1) * (prefixSumOfSums[rightIdx + 2] - prefixSumOfSums[i + 1]);
62
63 // rightContribution: sum of all subarrays ending before position i
64 long rightContribution = (long)(rightIdx - i + 1) * (prefixSumOfSums[i + 1] - prefixSumOfSums[leftIdx]);
65
66 // Add the contribution of strength[i] as minimum element
67 totalResult = (totalResult + minValue * ((leftContribution - rightContribution) % MOD)) % MOD;
68 }
69
70 // Handle negative modulo result
71 return (totalResult + MOD) % MOD;
72 }
73};
74
1function totalStrength(strength: number[]): number {
2 const n = strength.length;
3 const MOD = 1e9 + 7;
4
5 // Find the previous smaller element for each position
6 // leftBound[i] = index of the previous element smaller than strength[i]
7 const leftBound: number[] = new Array(n).fill(-1);
8 let monoStack: number[] = [];
9
10 for (let i = 0; i < n; i++) {
11 // Pop elements that are greater than or equal to current element
12 while (monoStack.length > 0 && strength[monoStack[monoStack.length - 1]] >= strength[i]) {
13 monoStack.pop();
14 }
15 if (monoStack.length > 0) {
16 leftBound[i] = monoStack[monoStack.length - 1];
17 }
18 monoStack.push(i);
19 }
20
21 // Find the next smaller or equal element for each position
22 // rightBound[i] = index of the next element smaller or equal to strength[i]
23 const rightBound: number[] = new Array(n).fill(n);
24 monoStack = []; // Reset the stack
25
26 for (let i = n - 1; i >= 0; i--) {
27 // Pop elements that are strictly greater than current element
28 while (monoStack.length > 0 && strength[monoStack[monoStack.length - 1]] > strength[i]) {
29 monoStack.pop();
30 }
31 if (monoStack.length > 0) {
32 rightBound[i] = monoStack[monoStack.length - 1];
33 }
34 monoStack.push(i);
35 }
36
37 // Build prefix sum array: prefixSum[i+1] = sum of strength[0..i]
38 const prefixSum: number[] = new Array(n + 1).fill(0);
39 for (let i = 0; i < n; i++) {
40 prefixSum[i + 1] = (prefixSum[i] + strength[i]) % MOD;
41 }
42
43 // Build prefix sum of prefix sums: prefixSumOfSums[i+1] = sum of prefixSum[0..i]
44 const prefixSumOfSums: number[] = new Array(n + 2).fill(0);
45 for (let i = 0; i <= n; i++) {
46 prefixSumOfSums[i + 1] = (prefixSumOfSums[i] + prefixSum[i]) % MOD;
47 }
48
49 // Calculate the total strength
50 let totalResult = 0;
51
52 for (let i = 0; i < n; i++) {
53 const minValue = strength[i];
54 const leftIdx = leftBound[i] + 1; // Left boundary of subarrays where strength[i] is minimum
55 const rightIdx = rightBound[i] - 1; // Right boundary of subarrays where strength[i] is minimum
56
57 // Calculate contribution of all subarrays where strength[i] is the minimum
58 // leftContribution: sum of all subarrays ending at or after position i
59 const leftContribution = (i - leftIdx + 1) * (prefixSumOfSums[rightIdx + 2] - prefixSumOfSums[i + 1]);
60
61 // rightContribution: sum of all subarrays ending before position i
62 const rightContribution = (rightIdx - i + 1) * (prefixSumOfSums[i + 1] - prefixSumOfSums[leftIdx]);
63
64 // Add the contribution of strength[i] as minimum element
65 // Use modulo arithmetic to handle large numbers
66 const contribution = ((leftContribution - rightContribution) % MOD) * minValue;
67 totalResult = (totalResult + contribution % MOD) % MOD;
68 }
69
70 // Handle negative modulo result by adding MOD if necessary
71 return (totalResult % MOD + MOD) % MOD;
72}
73
Time and Space Complexity
Time Complexity: O(n)
The algorithm consists of several linear passes through the array:
- First monotonic stack traversal to compute
left
array:O(n)
- each element is pushed and popped at most once - Second monotonic stack traversal to compute
right
array:O(n)
- each element is pushed and popped at most once - Computing prefix sum array using
accumulate
twice:O(n)
for each accumulate operation - Final loop to calculate the answer:
O(n)
- iterates through each element once withO(1)
operations per iteration
Total time complexity: O(n) + O(n) + O(n) + O(n) + O(n) = O(n)
Space Complexity: O(n)
The algorithm uses the following additional space:
left
array:O(n)
right
array:O(n)
stk
(reused twice):O(n)
in worst case when all elements are in increasing/decreasing orderss
array (double prefix sum):O(n+1)
=O(n)
Total space complexity: O(n)
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Handling of Equal Elements in Monotonic Stack
One of the most critical pitfalls in this problem is incorrectly handling equal elements when finding the boundaries where each element serves as the minimum.
The Pitfall:
If you use the same comparison operator (either >=
or >
) for both left and right boundary calculations, you'll count some subarrays multiple times when there are duplicate values.
For example, with strength = [2, 2, 2]
:
- If you use
>=
for both directions, all three elements would claim to be the minimum for the entire array - The subarray
[2, 2, 2]
would be counted three times instead of once
The Solution: Use asymmetric comparisons:
- For left boundaries: Pop elements that are
>= current
(greater than or equal) - For right boundaries: Pop elements that are
> current
(strictly greater)
This ensures that when there are equal elements, only the leftmost one is chosen as the minimum for subarrays containing multiple equal values.
# Correct approach: # Left boundary - use >= while stack and strength[stack[-1]] >= current_strength: stack.pop() # Right boundary - use > (strictly greater) while stack and strength[stack[-1]] > strength[i]: stack.pop()
2. Integer Overflow with Large Numbers
The Pitfall: The multiplication and addition operations can produce very large numbers before taking the modulo, potentially causing integer overflow in languages with fixed integer sizes.
The Solution: In Python, this isn't an issue due to arbitrary precision integers, but it's good practice to apply modulo operations frequently:
# Instead of calculating everything then taking modulo once: # total = (a - b) * v # ans = (ans + total) % MOD # Apply modulo at intermediate steps: contribution = ((positive_contribution - negative_contribution) % MOD * min_strength) % MOD total_strength_sum = (total_strength_sum + contribution) % MOD
3. Off-by-One Errors in Prefix Sum Calculations
The Pitfall:
The double prefix sum array indexing can be confusing. It's easy to use wrong indices when calculating the sum contributions, especially with the +1
and +2
offsets.
The Solution:
Remember that prefix_sum_of_prefix_sums
has two extra levels of padding:
- First
accumulate
adds one element at the beginning (initial=0) - Second
accumulate
adds another element at the beginning
So prefix_sum_of_prefix_sums[i+2]
corresponds to the sum of prefix sums up to and including index i
in the original array.
Always verify your indexing with small examples:
# For strength = [1, 2, 3] # After first accumulate: [0, 1, 3, 6] # After second accumulate: [0, 0, 1, 4, 10] # prefix_sum_of_prefix_sums[i+2] gives sum of prefix sums up to index i
4. Misunderstanding the Contribution Formula
The Pitfall:
The formula (a - b) * v
for calculating each element's contribution is not intuitive and can be easily misimplemented.
The Solution: Break down what each part represents:
a = (ss[r + 2] - ss[i + 1]) * (i - l + 1)
: Sum of all subarrays that END at positions fromi
tor
, multiplied by the number of possible starting positionsb = (ss[i + 1] - ss[l]) * (r - i + 1)
: Sum of all subarrays that START at positions froml
toi
, multiplied by the number of possible ending positions- The difference
(a - b)
gives the total sum of all subarrays where elementi
is the minimum
Test your understanding with a simple example before implementing.
Problem: Given a list of tasks and a list of requirements, compute a sequence of tasks that can be performed, such that we complete every task once while satisfying all the requirements.
Which of the following method should we use to solve this problem?
Recommended Readings
Stack Intro Imagine you have a pile of books on your desk If you want to add a new book you place it on top If you want to read a book you take it from the top And if you simply want to see which book is on the top you
Prefix Sum The prefix sum is an incredibly powerful and straightforward technique Its primary goal is to allow for constant time range sum queries on an array What is Prefix Sum The prefix sum of an array at index i is the sum of all numbers from index 0 to i By
Monotonic Stack Deque Intro If you'd prefer a video div class responsive iframe iframe src https www youtube com embed Dq_ObZwTY_Q title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div The word monotonic means a list or
Want a Structured Path to Master System Design Too? Don’t Miss This!