Перейти к основному содержимому

Один шаг при любом размере

O(1) означает константное время: операция выполняется за одно и то же количество шагов, независимо от того, содержит вход 5 элементов или миллион. Объём работы не растёт совсем.

Это лучшая из возможных сложностей. Типичные операции O(1) в TypeScript: чтение элемента массива по индексу, чтение значения Map по ключу, .length, добавление одного элемента в конец и простая арифметика.

Обратите внимание, чего O(1) не означает: это не значит «быстро», это значит «не становится медленнее при росте входных данных». Один константный шаг всё ещё может быть медленным шагом — но он остаётся одним шагом.


Поиск в массиве и в Map

Элемент массива находится в известной позиции в памяти, поэтому words[2] — это один переход: компьютер не проходит по элементам перед ним. То же самое чтение стоит столько же и в массиве из миллиона элементов.

Поиск в Map, например ages.get("Ben"), тоже в среднем занимает константное время: ключ напрямую указывает карте, где хранится значение. Второго возвращаемого значения «был ли он там» нет — get() имеет тип number | undefined и возвращает undefined, когда ключ отсутствует. ages.has("Ben") отвечает на тот же вопрос логическим значением, а ?? 0 превращает отсутствующее значение в значение по умолчанию. Все три операции выполняются за константное время.

Чтение элемента по индексу

Программа читает один элемент из массива из 5 элементов и один из массива в миллион элементов. Оба чтения — это один шаг, длина массива не играет никакой роли.

Prompt
Напишите программу на TypeScript с небольшим массивом из 5 слов и большим массивом из миллиона чисел, заполненным циклом. Прочитайте по одному элементу из каждого по индексу и выведите оба, чтобы показать, что чтение по индексу — это один шаг независимо от длины массива.
Вывод: программа на TypeScript и захваченный вывод
Read an element by index

Чтение значения по ключу

ages.get("Ben") сразу находит 25. Отсутствующий ключ "Dan" даёт undefined, а ages.has("Dan") равно false — по-прежнему за константное время. ages.get("Dan") ?? 0 выводит вместо этого 0.

Prompt
Напишите программу на TypeScript с Map, сопоставляющим имена и возраст: Ana 30, Ben 25 и Cleo 41. Найдите Ben и выведите значение вместе с has(), затем обратитесь к отсутствующему ключу Dan и снова выведите значение и has(). В конце выведите отсутствующее значение со значением по умолчанию ?? 0.
Вывод: программа на TypeScript и захваченный вывод
Read a value by key

Добавление в конец и простая арифметика

push() добавляет один элемент в конец массива. В большинстве случаев это один шаг. (Изредка массив должен вырасти и копируется, но в среднем стоимость одного push остаётся константной.)

Все мелкие операции — присваивания, сложения, сравнения, обмен двух значений — тоже O(1). Это те самые «шаги», в которых считаются все остальные классы сложности.

Добавление одного элемента

colors.push("жёлтый") помещает "жёлтый" в конец. Стоимость не зависит от того, сколько цветов уже находится в массиве.

Prompt
Напишите программу на TypeScript с массивом, содержащим красный, зелёный, синий. Выведите массив и его длину, добавьте в конец жёлтый, затем снова выведите массив и его длину.
Вывод: программа на TypeScript и захваченный вывод
Append one element

Обмен двух значений

[a, b] = [b, a] меняет два значения местами за один шаг константного времени — вспомогательная переменная не нужна. Строка начинается с точки с запятой, чтобы она читалась как отдельная инструкция, а не как индекс к строке выше.

Prompt
Напишите программу на TypeScript с двумя переменными a = 1 и b = 2. Выведите их, поменяйте местами с помощью деструктурирующего присваивания массива [a, b] = [b, a] и выведите их снова.
Вывод: программа на TypeScript и захваченный вывод
Swap two values