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

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

Мышление и сложность: чтение кода

Суть Читай реальные фрагменты кода, считай шаги, выводи Big-O по времени и памяти, предсказывай поведение и находи баг сложности или корректности.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

Анализ закрепляется, только когда делаешь его на реальном коде. Прочитай каждый фрагмент, посчитай циклы и память и определи сложность — ровно тот ход, который делаешь на ревью пул-реквеста или оценивая решение.

Цель

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

Фрагмент 1 — во что обходится вложенность?

function countCloserPairs(points, threshold) {
  let count = 0;
  for (let i = 0; i < points.length; i++) {
    for (let j = i + 1; j < points.length; j++) {
      if (Math.abs(points[i] - points[j]) < threshold) {
        count++;
      }
    }
  }
  return count;
}
Викторина

Каковы сложности по времени и памяти у countCloserPairs на n точках?

Фрагмент 2 — предскажи число сравнений

function linearSearch(arr, target) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === target) return i;
  }
  return -1;
}
// arr = [0, 1, 2, ..., 999]  (1000 отсортированных элементов)
Викторина

Для arr = [0..999] какое утверждение про linearSearch верно?

Фрагмент 3 — один результат, разная стоимость

// Версия A
function sumToNLoop(n) {
  let sum = 0;
  for (let i = 1; i <= n; i++) sum += i;
  return sum;
}

// Версия B
function sumToNFormula(n) {
  return n * (n + 1) / 2;
}
Викторина

Обе функции возвращают одно значение. Как соотносятся их сложности?

Фрагмент 4 — баг, который тест может пропустить

function average(numbers) {
  let sum = 0;
  for (let i = 0; i < numbers.length; i++) {
    sum += numbers[i];
  }
  return sum / numbers.length;
}
Викторина

Сложность в порядке — время O(n), память O(1). Но какой крайний случай ломает корректность и почему это здесь важно?

Итог

Снимать сложность с кода — фиксированный приём: найди доминирующую работу и оставь только этот член; перемножай вложенные циклы и складывай последовательные фазы; считай структуры памяти, а не итерации цикла, для памяти; и помни, что замкнутая формула может заменить цикл O(n) на O(1). Затем проверь вторую ось — алгоритм с идеальной Big-O всё ещё может быть неверен на крайнем случае (пустой вход, деление на ноль), которого твои тесты не коснулись.

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

Trademarks belong to their respective owners. Editorial reference only.