Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 8 – Stacks and monotonic stacks

Contribution counting with monotonic stacks

Sum the minimum of every subarray in O(n): count how many subarrays each element is the minimum of, with monotonic stacks, ties counted once.

  • Advanced
  • 15 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Java temurin-25.0.4+101.0.LTS, Node.js 24.21.0 and quickjs 0.32.0
  • By MySmartCoPilot
Free intro, Pro: 3 of 15 minutes free
Free: The problem: the cheapest item of every basket. With a pass: the other 10 sections and 3 interview answers, about 12 minutes.

What you will learn

  • Count how many subarrays have each element as their minimum, from its nearest smaller elements
  • Compute the sum of the minimums of all subarrays in O(n) with one pass of a monotonic stack
  • Prove that every subarray is counted exactly once when values repeat
  • Prevent overflow and lost precision under a modulus of 10⁹ + 7 in Java, C++, Go and JavaScript
  • Compute the sums of the maximums and of the spreads (maximum minus minimum) the same way

Before you start

What you’ll learn · Before you start

What you will learn

  • Count how many subarrays have each element as their minimum, from its nearest smaller elements
  • Compute the sum of the minimums of all subarrays in O(n) with one pass of a monotonic stack
  • Prove that every subarray is counted exactly once when values repeat
  • Prevent overflow and lost precision under a modulus of 10⁹ + 7 in Java, C++, Go and JavaScript
  • Compute the sums of the maximums and of the spreads (maximum minus minimum) the same way

Before you start

On this page

contribution counting: Summing a value over all subarrays by asking, for each element, in how many subarrays it decides the value, and adding its value times that count, instead of visiting every subarray. turns a sum over all subarrays into a sum over the elements: in 4, 2, 5, 3 the 2 is the minimum of 6 subarrays, so it adds 2 × 6 = 12. Instead of finding the minimum of each of the n(n + 1)/2 subarrays, it asks how many subarrays each element is the minimum of, and adds value × count. That count is a product of two choices, where such a subarray may start and where it may end, bounded by the nearest smaller element on each side, which a monotonic stack: A stack whose values stay in order from bottom to top, because each new item first pops every item it settles. It finds the nearest earlier or later larger, or smaller, item for every item in one pass. More in “Stack patterns: nesting and undo” finds for every element in O(n). The whole sum then takes O(n) time instead of O(n²). Its best-known case is the sum of subarray minimums, stated here as the cheapest item of every basket on a shelf. Sums of maximums and of spreads, maximum minus minimum, follow from the same count.

The problem: the cheapest item of every basket

The problem

A shelf holds n items in a row, with prices p[0..n − 1]. A basket is any run of one or more neighbouring items, and its floor is the price of its cheapest item. Return the sum of the floors of all n(n + 1)/2 baskets, modulo 10⁹ + 7. Limits: 1 ≤ n ≤ 300,000 and 1 ≤ p[i] ≤ 10⁹.

Four examples, which every program in this lesson runs:

  1. [4, 2, 5, 3] gives 27: the four single items add 14, the three pairs 2 + 2 + 3, the two triples 2 + 2 and the whole shelf 2.
  2. [2, 2, 2] gives 12: six baskets, each with a floor of 2.
  3. [7] gives 7.
  4. [10⁹, 10⁹] gives 999,999,986, which is 3 × 10⁹ reduced modulo 10⁹ + 7.

The brute force: every basket with its cheapest item

Start a basket at every item and extend it to the right, keeping the cheapest price seen so far and adding it to the total. The run counts the baskets on random shelves:

Every basket, with its cheapest price Python · brute/floors_brute.py
"""The sum of the cheapest price of every basket, the brute force: every run of neighbouring items."""

import random

MOD = 1_000_000_007


def floor_total_brute(prices):
    """The sum, modulo 10**9 + 7, of the lowest price of every basket, and how many baskets were tried."""
    total = baskets = 0
    for i in range(len(prices)):
        lowest = prices[i]
        for j in range(i, len(prices)):  # the basket of items i..j
            lowest = min(lowest, prices[j])
            total = (total + lowest) % MOD
            baskets += 1
    return total, baskets


print(floor_total_brute([4, 2, 5, 3])[0])
print(floor_total_brute([2, 2, 2])[0])
print(floor_total_brute([7])[0])
print(floor_total_brute([10**9, 10**9])[0])

rng = random.Random(907)
for n in (1_000, 2_000):
    shelf = [rng.randint(1, 10**9) for _ in range(n)]
    print(f"{n:,} items: {floor_total_brute(shelf)[1]:,} baskets")

Output

27
12
7
999999986
1,000 items: 500,500 baskets
2,000 items: 2,001,000 baskets

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 floors_brute.py

There is no shortcut inside the loops: every one of the n(n + 1)/2 baskets is visited, 45,000,150,000 of them at the limit of 300,000 items. At 10⁸ simple steps a second that is seven and a half minutes of C++. The total itself grows just as fast: it can reach 4.5 × 10¹⁹, beyond the largest 64-bit integer, about 9.2 × 10¹⁸, which is why the problem asks for it modulo 10⁹ + 7.

Checkpoint

Check: What visiting every basket costs

  1. One question How many baskets does the brute force visit on a shelf of 4,000 items?

    Type a number.

    A hint

    A basket is a start and an end with the start at or before the end.

    Show the answer: One question

    Answer: 8002000 baskets

    n(n + 1)/2 = 4,000 × 4,001 / 2 = 8,002,000. The recorded run counted 2,001,000 for 2,000 items by the same formula: twice the items, about four times the baskets.

What to notice

Turn the question round: for each item, in how many baskets is it the cheapest? Such a basket must start after the nearest cheaper item on the left and end before the nearest cheaper item on the right, and any such start and end will do. In the table below, item 1 is the cheapest of 2 starts × 3 ends = 6 baskets, so it adds 2 × 6 = 12.

A triangle of the ten baskets of 4, 2, 5, 3, each with its cheapest price; the baskets each item is cheapest in form blocks.The cheapest price of every basket of 4, 2, 5, 3the basket ends at item0123startsat item01234222222533Item 1, price 2, is the cheapest in the shadedblock: 2 starts × 3 ends = 6 baskets.

The baskets an item is the cheapest of form one block of starts and ends

Text description of the diagram

The table has a row for each item where a basket can start (0 to 3) and a column for each item where it can end (0 to 3), so each of the ten baskets of the shelf 4, 2, 5, 3 is one cell on or above the diagonal. Each cell shows the basket's cheapest price.

  1. Row 0 reads 4, 2, 2, 2: the basket of item 0 alone costs 4 at its cheapest, and every longer basket starting there contains item 1, price 2.
  2. Row 1 reads 2, 2, 2: every basket starting at item 1 contains it.
  3. Row 2 reads 5, 3, and row 3 reads 3.

Thick outlines group the cells by the item that is their cheapest. Item 0 owns one cell, item 2 one cell, item 3 the two cells of column 3 in rows 2 and 3, and item 1, shaded, a block of 2 rows by 3 columns: baskets that start at item 0 or 1 and end at item 1, 2 or 3. That block has 2 × 3 = 6 cells, so item 1 adds 2 × 6 = 12 to the total. The four blocks add 4 + 12 + 5 + 6 = 27, the sum of all ten cells.

The nearest cheaper item on each side is the question that a monotonic stack answers, as in the lesson on next greater elements. Equal prices need one more rule, so that a basket with two cheapest items is counted once.

Checkpoint

Check: The baskets each item is the cheapest of

  1. One question On the shelf [4, 2, 5, 3], how many baskets have item 3 (price 3) as their cheapest item?

    Type a number.

    Show the answer: One question

    Answer: 2 baskets

    The nearest cheaper item on its left is item 1 (price 2), so a basket may start at item 2 or 3; nothing comes after item 3, so it must end there. That is 2 starts × 1 end: the baskets 2..3 and 3..3, which add 3 × 2 = 6.

Practice that adapts to you

Practise this lesson

6 questions about 8 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 6 Why does the problem ask for the total modulo 10⁹ + 7?

    Choose one answer.

    Show the answer: Question 1 of 6

    Answer: The total can reach 4.5 × 10¹⁹, beyond the largest 64-bit integer

    300,000 items give about 4.5 × 10¹⁰ baskets, each with a floor up to 10⁹, so the total can reach 4.5 × 10¹⁹, beyond what a 64-bit integer holds.

  2. Question 2 of 6 At the limit of 300,000 items the brute force visits 45,000,150,000 baskets. At 10⁸ simple steps a second, about how long is that?

    Choose one answer.

    Show the answer: Question 2 of 6

    Answer: About seven and a half minutes

    45,000,150,000 ÷ 10⁸ ≈ 450 seconds, seven and a half minutes of C++, where a time limit allows about a second.

  3. Question 3 of 6 Which shelf of 300,000 items has the largest total before the modulus is applied?

    Choose one answer.

    Show the answer: Question 3 of 6

    Answer: Every price 10⁹, for a total of about 4.5 × 10¹⁹

    The total is the sum of one floor per basket. With every price at 10⁹ each of the n(n + 1)/2 ≈ 4.5 × 10¹⁰ baskets adds 10⁹, about 4.5 × 10¹⁹, beyond the largest 64-bit integer.

  4. Question 4 of 6 On [4, 2, 5, 3], item 1 (price 2) is the cheapest of how many baskets, and what does it add to the total?

    Choose one answer.

    Show the answer: Question 4 of 6

    Answer: 6 baskets, adding 12

    Nothing on either side of item 1 is cheaper, so a basket may start at item 0 or 1 and end at item 1, 2 or 3: 2 × 3 = 6 baskets, which add 2 × 6 = 12.

  5. Question 5 of 6 Why are the baskets an item is the cheapest of exactly the pairs of a possible start and a possible end?

    Choose one answer.

    Show the answer: Question 5 of 6

    Answer: Any start after the nearest cheaper item on the left with any end before the nearest cheaper item on the right keeps the item the cheapest

    The start can be any item after the nearest cheaper item on the left, up to the item itself, and the end any item from the item up to just before the nearest cheaper item on the right. Each pair is one basket, so the count is starts × ends.

  6. Question 6 of 6 On [2, 2], each item counts the baskets in which no item is strictly cheaper than it. How often is the basket [2, 2] counted?

    Choose one answer.

    Show the answer: Question 6 of 6

    Answer: Twice, once for each 2

    Both items are a cheapest item of [2, 2], so a rule that only stops at strictly cheaper items counts it twice, and the total comes out too large. One more rule is needed so that each basket is counted once.

Each item’s share, in one pass with a stack Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • A dry run on [4, 2, 5, 3]
  • Equal prices: strict on one side, and the proof that each basket counts once
  • The modulus, and the products that overflow on the way
  • The code in 14 languages, each exact under the modulus
  • A stress test, and edge cases
  • Maximums and spreads: the same loop, reversed
  • Practise: the total spread of every basket
    • Add up the price spread of every basket
  • Variants and follow-up questions, answered
  • Interview questions
    • Your sum of subarray minimums comes out too large whenever the input repeats values. Explain why, fix it, and prove that every subarray is now counted exactly once.
    • The sum of subarray minimums for 300,000 prices of up to 10⁹ must be returned modulo 10⁹ + 7. Where can a Java or JavaScript solution lose exactness, and how do you keep every step exact?
    • For an array of daily prices, return the sum over all subarrays of (maximum − minimum), modulo 10⁹ + 7. Give an O(n) method, the cost of the naive one at n = 10⁵, and how you handle the subtraction under the modulus.
  • Key takeaways

1 diagram · 5 runnable examples (Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 36 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Terms in this lesson

contribution counting
Summing a value over all subarrays by asking, for each element, in how many subarrays it decides the value, and adding its value times that count, instead of visiting every subarray.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.