Монотонный стек

Держим в стопке элементы, которые ещё ждут ответа, по порядку от большего к меньшему. Новый элемент снимает сверху всех, кого он больше, и сразу даёт им ответ, поэтому никого не сравнивают со всеми следующими.

P08 Монотонный стек1×

Пример задачи: для каждого дня из [73, 74, 75, 71, 69, 72, 76] узнать, сколько дней ждать потепления.

073174275371469572676градусыответ0000000стек—
ещё не дошлитекущий деньждёт в стекепроверяемый верхответ найден

Все ответы пока 0

answer = [0, 0, 0, 0, 0, 0, 0]stack = –day = –prev = –
01/42
сначала · назад · пуск · шаг
Скорость
1function dailyTemperatures(temps):
2 answer = list of len(temps) zeros
3 stack = empty stack
4 for day from 0 to len(temps) - 1:
5 while day is warmer than the top:
6 prev = pop from stack
7 answer[prev] = day - prev
8 push day onto stack
9 return answer

← → шаг · пробел — пауза

Как узнать

для каждого элемента ближайший следующий или предыдущий, который больше или меньше: следующий более тёплый день, ближайший столбик выше.

Как решать такие задачи

  1. Определи, чего ждёт каждый элемент: следующего большего или следующего меньшего.
  2. Держи в стеке индексы тех, кто ещё ждёт. Индексы, а не значения, чтобы считать расстояния.
  3. Для каждого нового элемента снимай верх, пока новый его превосходит (больше или меньше — смотря что ищешь). Каждый снятый индекс нашёл ответ.
  4. Положи новый индекс. У индексов, оставшихся в стеке в конце, ответа нет: дай им значение по умолчанию.

Где встречается

  • Выпуклая оболочка. Алгоритм Грэхема, которым GEOS и PostGIS считают ST_ConvexHull, обходит точки по кругу и держит границу оболочки в стеке. Новая точка снимает с верха те, что оказались внутри, так же как в монотонном стеке новый элемент снимает тех, кого он побил.
  • Разбор формул. Алгоритм «сортировочная станция» держит операторы в стеке по возрастанию приоритета. Новый оператор сначала снимает с верха всех, кто связывает не слабее его. Так калькуляторы и парсеры формул превращают 2 + 3 × 4 в порядок вычислений.