awesome-everything EN
↑ Обратно к восхождению

Алгоритмы с нуля

Списки, стеки, очереди: чтение кода

Суть Читай реальные сниппеты на JavaScript — баг pointer в развороте, баг удаления по значению, сломанную array queue и паттерн monotonic stack — и выбирай самый рычажный диагноз или фикс.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

Баги pointer в коде linked list не падают громко — они тихо портят структуру. Читай каждый сниппет, прокрути pointer в голове и выбери, что senior-инженер пометит первым.

Цель

Потренируй цикл, который ты гоняешь на каждом разборе списков/стеков/очередей: читай движения pointer, предскажи, где теряется узел или где неверно заявлена сложность, и назови точный фикс.

Сниппет 1 — разворот, теряющий хвост

function reverse(head) {
  let prev = null;
  let current = head;
  while (current !== null) {
    current.next = prev;   // развернуть pointer
    prev = current;
    current = current.next; // продвинуться
  }
  return prev;
}
Викторина

Что произойдёт при запуске на [10] -> [20] -> [30]?

Сниппет 2 — удаление по значению без sentinel

function deleteValue(head, target) {
  let current = head;
  while (current !== null) {
    if (current.value === target) {
      current = current.next; // "удалить" его
    }
    current = current.next;
  }
  return head;
}
Викторина

Удаляет ли это целевой узел из списка?

Сниппет 3 — array queue под нагрузкой

class Queue {
  constructor() { this.items = []; }
  enqueue(x) { this.items.push(x); }
  dequeue() { return this.items.shift(); }
}
// Драйвер: поток из 1 000 000 пар enqueue/dequeue
Викторина

Очередь корректна, но нагрузочный тест показывает, что она еле ползёт. В чём причина и самый рычажный фикс?

Сниппет 4 — паттерн monotonic stack

function dailyWarmerWait(temps) {
  const result = new Array(temps.length).fill(0);
  const stack = []; // индексы, убывающие температуры
  for (let i = 0; i < temps.length; i++) {
    while (stack.length && temps[i] > temps[stack[stack.length - 1]]) {
      const j = stack.pop();
      result[j] = i - j;   // дней до более тёплой температуры
    }
    stack.push(i);
  }
  return result;
}
Викторина

Для temps [73, 74, 75, 71, 69, 72, 76, 73] что это возвращает и какова сложность?

Итог

Каждый баг списков/стеков/очередей читается в pointer и cost model. Разворот должен сохранить преемника до перезаписи current.next, иначе теряет хвост. Удаление должно переставить предшественника — перемещение локальной ссылки не меняет ничего — а sentinel-голова стирает спецслучай головы. FIFO queue никогда не делает dequeue через shift; используй pointer head/tail или circular buffer для O(1). А monotonic stack остаётся линейным, потому что каждый индекс пушится один раз и попается максимум один раз, независимо от внутреннего while.

Продолжить восхождение ↑Списки, стеки, очереди: собери тулкит последовательностей
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.