SprintCode.pro

Подготовка к алгоритмическим задачам

Super

Шпаргалки по алгоритмам: компактный справочник

10 мин чтения
алгоритмы
структуры данных
сортировка
поиск
графы
динамическое программирование

Шпаргалки по алгоритмам

1. Структуры данных: сложность операций

Структура данныхДоступПоискВставкаУдалениеПримечания
Массив (Array)O(1)O(n)O(n)O(n)Быстрый доступ, медленные изменения
Связный списокO(n)O(n)O(1)O(1)Быстрые вставки в начало/конец
Стек (Stack)O(n)O(n)O(1)O(1)LIFO: последним пришёл — первым ушёл
Очередь (Queue)O(n)O(n)O(1)O(1)FIFO: первым пришёл — первым ушёл
Хеш-таблица-O(1)O(1)O(1)Возможны коллизии, O(n) в худшем случае
Бинарное дерево поискаO(log n)O(log n)O(log n)O(log n)В среднем, может O(n) для несбалансированного
AVL деревоO(log n)O(log n)O(log n)O(log n)Автоматически балансируется
Красно-чёрное деревоO(log n)O(log n)O(log n)O(log n)Менее строгое балансирование, чем AVL
Куча (Heap)O(1)O(n)O(log n)O(log n)Для извлечения максимума/минимума
Префиксное дерево (Trie)O(m)O(m)O(m)O(m)m = длина ключа, для строк

2. Алгоритмы сортировки

АлгоритмЛучший случайСредний случайХудший случайПамятьСтабильность
Bubble SortO(n)O(n²)O(n²)O(1)Стабильный
Selection SortO(n²)O(n²)O(n²)O(1)Нестабильный
Insertion SortO(n)O(n²)O(n²)O(1)Стабильный
Merge SortO(n log n)O(n log n)O(n log n)O(n)Стабильный
Quick SortO(n log n)O(n log n)O(n²)O(log n)Нестабильный
Heap SortO(n log n)O(n log n)O(n log n)O(1)Нестабильный
Counting SortO(n + k)O(n + k)O(n + k)O(n + k)Стабильный
Radix SortO(nk)O(nk)O(nk)O(n + k)Стабильный
Bucket SortO(n + k)O(n + k)O(n²)O(n + k)Стабильный

Реализация быстрой сортировки (Quick Sort):

function quickSort(arr, left = 0, right = arr.length - 1) { if (left < right) { const pivotIndex = partition(arr, left, right); quickSort(arr, left, pivotIndex - 1); quickSort(arr, pivotIndex + 1, right); } return arr; } function partition(arr, left, right) { const pivot = arr[right]; let i = left - 1; for (let j = left; j < right; j++) { if (arr[j] <= pivot) { i++; [arr[i], arr[j]] = [arr[j], arr[i]]; } } [arr[i + 1], arr[right]] = [arr[right], arr[i + 1]]; return i + 1; }

3. Алгоритмы поиска

АлгоритмСложностьТребованияПримечания
Линейный поискO(n)-Работает с любыми данными
Бинарный поискO(log n)Отсортированный массивДелит массив пополам на каждом шаге
Поиск в глубину (DFS)O(V + E)ГрафИспользует стек
Поиск в ширину (BFS)O(V + E)ГрафИспользует очередь
Поиск подстрокиO(n + m)СтрокиАлгоритм КМП (Кнута-Морриса-Пратта)
ХешированиеO(1)Хеш-функцияВ среднем случае

Реализация бинарного поиска:

function binarySearch(arr, target) { let left = 0; let right = arr.length - 1; while (left <= right) { const mid = Math.floor((left + right) / 2); if (arr[mid] === target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; // Элемент не найден }

4. Алгоритмы на графах

АлгоритмСложностьПрименение
DFSO(V + E)Поиск связности, циклов, топологическая сортировка
BFSO(V + E)Кратчайший путь (невзвешенный граф)
DijkstraO((V + E) log V)Кратчайший путь с неотрицательными весами
Bellman-FordO(V * E)Кратчайший путь, обработка отрицательных весов
Floyd-WarshallO(V³)Кратчайшие пути между всеми вершинами
PrimO(E log V)Минимальное остовное дерево
KruskalO(E log E)Минимальное остовное дерево
Топологическая сортировкаO(V + E)Упорядочивание направленного ациклического графа

Алгоритм Дейкстры (реализация):

function dijkstra(graph, start) { const distances = {}; const visited = {}; const previous = {}; const nodes = Object.keys(graph); // Инициализация for (let node of nodes) { distances[node] = Infinity; previous[node] = null; } distances[start] = 0; while (nodes.length) { // Находим узел с минимальным расстоянием nodes.sort((a, b) => distances[a] - distances[b]); const closest = nodes.shift(); if (distances[closest] === Infinity) break; for (let neighbor in graph[closest]) { const distance = distances[closest] + graph[closest][neighbor]; if (distance < distances[neighbor]) { distances[neighbor] = distance; previous[neighbor] = closest; } } visited[closest] = true; } return { distances, previous }; }
Пройди собеседование в топ-компанию
Платформа для подготовки

Решай алгоритмические задачи как профи

✓ Популярные алгоритмы✓ Разбор решений✓ AI помощь
Начать сейчас
Программист за работой

5. Динамическое программирование

ЗадачаСложностьКраткое описание
Числа ФибоначчиO(n)F(n) = F(n-1) + F(n-2)
Задача о рюкзаке (0/1)O(n*W)Максимизация ценности при ограничении веса
Наибольшая общая подпоследовательностьO(n*m)Длиннейшая подпоследовательность в обеих строках
Редакционное расстояние (Левенштейн)O(n*m)Минимальное число операций для превращения одной строки в другую
Задача о разбиении суммыO(n*sum)Разделить набор на две части с равной суммой
Наибольшая возрастающая подпоследовательностьO(n²) или O(n log n)Длиннейшая возрастающая последовательность

Задача о рюкзаке (динамическое программирование):

function knapsack(weights, values, capacity) { const n = weights.length; const dp = Array(n + 1).fill().map(() => Array(capacity + 1).fill(0)); for (let i = 1; i <= n; i++) { for (let w = 0; w <= capacity; w++) { if (weights[i - 1] <= w) { dp[i][w] = Math.max( values[i - 1] + dp[i - 1][w - weights[i - 1]], dp[i - 1][w] ); } else { dp[i][w] = dp[i - 1][w]; } } } return dp[n][capacity]; }

6. Строковые алгоритмы

АлгоритмСложностьПрименение
Кнута-Морриса-Пратта (КМП)O(n + m)Поиск подстроки в строке
Рабина-КарпаO(n + m)Поиск подстроки с хешированием
Бойера-МураO(n + m)Эффективный поиск подстроки
Z-функцияO(n)Строковый поиск и сопоставление
Trie (префиксное дерево)O(m)Поиск строк, автодополнение
Суффиксный массив/деревоO(n log n)/O(n)Полнотекстовый поиск, работа с суффиксами
Расстояние ЛевенштейнаO(n * m)Редактирование расстояния между строками

Построение Z-функции:

function zFunction(s) { const n = s.length; const z = Array(n).fill(0); let left = 0, right = 0; for (let i = 1; i < n; i++) { if (i <= right) { z[i] = Math.min(right - i + 1, z[i - left]); } while (i + z[i] < n && s[z[i]] === s[i + z[i]]) { z[i]++; } if (i + z[i] - 1 > right) { left = i; right = i + z[i] - 1; } } return z; }

7. Геометрические алгоритмы

АлгоритмСложностьПрименение
Выпуклая оболочка (Graham Scan)O(n log n)Построение минимальной выпуклой оболочки
Пересечение отрезковO(n²) или O(n log n)Определение пересечений между отрезками
Ближайшая пара точекO(n log n)Нахождение двух ближайших точек
Триангуляция ДелонеO(n log n)Оптимальная триангуляция множества точек
Алгоритм заметания прямойO(n log n)Решение геометрических задач перебором

Проверка, лежит ли точка внутри многоугольника:

function pointInPolygon(point, polygon) { const x = point[0], y = point[1]; let inside = false; for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { const xi = polygon[i][0], yi = polygon[i][1]; const xj = polygon[j][0], yj = polygon[j][1]; const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if (intersect) inside = !inside; } return inside; }

8. Криптографические алгоритмы

АлгоритмТипПрименение
SHA-256ХешированиеЦелостность данных
AESСимметричное шифрованиеКонфиденциальность данных
RSAАсимметричное шифрованиеЗащищенная передача ключей
ECDSAЦифровая подписьАутентификация
HMACАутентификация сообщенийПроверка целостности и источника

9. Алгоритмы машинного обучения

АлгоритмТипПрименение
k-ближайших соседей (k-NN)КлассификацияРаспознавание образов
Линейная регрессияРегрессияПрогнозирование числовых значений
Дерево решенийКлассификация/РегрессияИнтерпретируемые модели
Случайный лесАнсамблевый методУлучшение точности и надежности
Градиентный бустингАнсамблевый методПостроение сильных моделей
Логистическая регрессияКлассификацияПрогнозирование вероятностей
Метод опорных векторов (SVM)КлассификацияРабота с разделяющей гиперплоскостью
k-meansКластеризацияРазделение данных на группы

10. Практические советы по оптимизации

  1. Выбор правильной структуры данных

    • Частый доступ по индексу? → Массив
    • Частые вставки/удаления? → Связный список
    • Быстрый поиск по ключу? → Hash Map
    • Диапазонные запросы? → Дерево отрезков
  2. Оптимизация памяти

    • Используйте битовые операции для компактного хранения данных
    • Предварительное выделение памяти для массивов
    • Удаление ненужных промежуточных данных
  3. Оптимизация времени

    • Предварительные вычисления (префиксные суммы и т.д.)
    • Использование кеширования (мемоизация в DP)
    • Избегайте лишних проходов по данным
  4. Профилирование и отладка

    • Измерение времени работы критических участков
    • Нахождение узких мест в алгоритме
    • Пошаговая отладка для правильного понимания алгоритма