Признак в условии
- «следующий больший / меньший элемент»
- «сколько дней до более тёплого»
- «наибольший прямоугольник в гистограмме»
- элементы «съедают» друг друга по правилу
Идея
Стек хранит индексы, значения в нём монотонны. Пока новый элемент нарушает монотонность, снимаем вершину - для неё текущий элемент и есть ответ. Каждый индекс кладётся и снимается один раз, поэтому O(n) несмотря на while.
Шаблон
const res = new Array(nums.length).fill(0);
const stack = [];
for (let i = 0; i < nums.length; i++) {
while (stack.length && nums[i] > nums[stack[stack.length - 1]]) {
const j = stack.pop();
res[j] = i - j;
}
stack.push(i);
}
Сложность
Время O(n), память O(n).
Частые ошибки
- в стеке хранятся значения, а потом нужен индекс
- строгое и нестрогое сравнение путают (влияет на обработку равных элементов)
- забывают, что оставшиеся в стеке индексы ответа не получили
Мнемоника
«Пока вершина хуже - она нашла свой ответ»
Не путать с
- Стек - признак монотонного - вопрос «следующий больший/меньший» или «какой участок этот элемент доминирует»
- Куча и top-K - куча даёт k лучших в произвольном порядке прихода; монотонный стек - ближайший по позиции, и он линейный
Задачи на этот паттерн
- следующий больший элемент
- столкновение астероидов
- сколько воды удержится