Как можно сравнить 2 функции или алгоритма, выполняющие одну задачу, но имеющие разную реализацию между собой?
Зачем спрашивают
Выяснить, знаком ли кандидат с понятием сложности алгоритмов, какие существует критерии оценки и сравнения сложность алгоритмов.
Ответ
Коротко:
Критерии оценки алгоритмов:
- Time complexity
- Space complexity
- В редких случаях — стабильность алгоритма (например, для сортировок)
Выражаются или описываются big O нотацией.
Подробнее:
Big O нотация — это математическая нотация, способ описания сложности алгоритма, то есть того, как быстро растут время выполнения или использование памяти алгоритмом в зависимости от размера входных данных.
Пример:
function sumArray(arr) { let sum = 0; // O(1) по памяти for (let i = 0; i < arr.length; i++) { // O(n) по времени sum += arr[i]; } return sum; }
- Time complexity = O(n) (цикл по каждому элементу).
- Space complexity = O(1) (используем только одну переменную
sum).
Обе оценки выражаются через Big O, но они разные по смыслу.
Компромиссы
- Big O описывает верхнюю границу роста функции. На практике чаще всего анализируют худший случай, но иногда используют и средний, и лучший
- Нужно смотреть не только теорию, но и профилировать код на практике.
Встречные вопросы
- Big O всегда только про скорость выполнения?
- Приведите примеры часто встречающихся сложностей
- В нотации, например, O(n), что такой O? Что такоe n?
- Для чего измеряются стабильность алгоритма?
Красные флаги
- Ответ без объяснения («Ну это просто big O»).
- Сравнение только по скорости без упоминания памяти.
- Сравнение по «читабельности» кода (сигнал, что человек не понимает алгоритмы)
Практика
Задача 1
// Какая сложность по времени и памяти? И почему? function sumArray(arr) { let sum = 0; for (const item of arr) { sum += item; } return sum; }
Задача 2
// Какая сложность по времени и памяти? И почему? // Можно ли улучшить результат? function contains(arr, target) { for (const item of arr) { if (item === target) return true; } return false; }
Задача 3
// Какая сложность по времени и памяти? И почему? function printPairs(arr) { for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr.length; j++) { console.log(arr[i], arr[j]); } } }
Задача 4
// Какая сложность по времени и памяти? И почему? function removeDuplicates(arr) { return [...new Set(arr)]; }
Задача 5
// Написать проверяющую функцию, есть ли в массиве два числа, сумма которых равна target // Целевая сложность -- O(n) function hasPairWithSum(arr, target) { return false; }