A row of daily temperatures is drawn as a bar skyline and walked one day at a time, playing Daily Temperatures (LC 739): for every day, how long until a warmer one. The stack of days still waiting sits to the right as a leaning column of blocks. Each arriving day compares against the top; every colder block is knocked off — its wait recorded, an arc drawn back to the day that resolved it — and then the new day joins the column. Nothing on the column is ever warmer than what is under it, which is the whole invariant.
The point of the piece is what sits underneath. Two counters, per step:
comparisons this step, which spikes hard whenever one tall day clears
half the column — the inner while loop, looking unmistakably quadratic
while it happens — and pushes + pops so far, which climbs in a
dead-straight line under a dashed 2·(i+1) ceiling and never bends, because
every day is pushed exactly once and popped at most once no matter how the
cascades fall. The gap between those two counters is amortized analysis: an
expensive-looking step and a linear total, on screen at the same time, which
is exactly what the O(n) claim asks you to take on faith at a whiteboard.
Drag any bar to reshape the skyline and the run rebuilds live at the same step; build the worst case you can and watch the straight line stay straight. The sawtooth shape (long descents, each ended by one tall day) is the loudest; falling is the quiet O(n)-space worst case where nothing ever pops; rising is the flat one-comparison-per-day floor.
Reuse
src/skyline.js is a framework-free ES module:
dailyTemperatures(temps)— the plain answer, as you would write it in an interview.makeTemps(n, { drift, rand })— a random walk of temperatures in the problem’s 30..100 range, with slopes and cliffs.PRESETS—example,random,rising,falling,sawtooth, each a function ofn.cleanTemps(input, max)— user text into clamped integers.simulate(temps)— one frame per day with the days it popped (and their waits), the comparisons it cost, the stack after it, the running push and pop totals, and the answer array so far. Same trace-per-tick shape aswindow,siftandrho.
No rendering or timers in the module; the canvas demo is reference code.
Gotchas
- “Warmer” is strict. Equal temperatures do not pop —
[70, 70, 75]is[2, 1, 0], not[1, 1, 0]— and the module’s comparison is<, deliberately. Loosen it and the answers change while the counters look the same. - The comparison counter counts the check that fails and ends the loop too, so a step that pops nothing still costs one comparison unless the stack was empty. Change the accounting and the spikes shift; the straight line does not.
- The demo bundles its own copy of
skyline.js(self-contained by contract); re-copy after editingsrc/.