TypeScript на LeetCode: от новичка до профи за 30 дней

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Почему TypeScript — идеальный язык для LeetCode?

Если вы до сих пор решали задачи на LeetCode на JavaScript — самое время перейти на TypeScript. Почему? Потому что строгая типизация отсекает целый класс ошибок ещё до запуска кода. Вы не сможете случайно передать строку туда, где ожидается число, а компилятор сам подскажет, какие методы доступны у объекта. Это как ездить на машине с автопилотом — быстрее, безопаснее и приятнее.

LeetCode — это не просто платформа для зубрёжки алгоритмов. Это тренировочный полигон, где вы оттачиваете навыки, которые реально нужны в продакшене. А TypeScript сегодня — стандарт де-факто для enterprise-разработки. Компании вроде Google, Microsoft и Airbnb ищут разработчиков, которые умеют писать типизированный код. Так что, решая задачи на LeetCode на TypeScript, вы убиваете двух зайцев: готовитесь к собеседованию и прокачиваете реальные скиллы.

В этой статье мы разберём, с чего начать, какие типы и структуры данных изучить, и пройдём 3 задачи разного уровня — от лёгкой до сложной. Поехали!

Что нужно знать перед стартом

Прежде чем нырять в пул задач, убедитесь, что у вас есть база. TypeScript — это надстройка над JavaScript, поэтому сначала нужно уверенно владеть JS: замыкания, промисы, методы массивов, работа с объектами. Без этого TypeScript будет казаться просто лишним синтаксическим сахаром.

Основные типы, которые пригодятся на LeetCode

  • number, string, boolean — база, без них никуда
  • number[], string[] — массивы, встречаются в 90% задач
  • Record<string, number> — объект как словарь (hash map)
  • Map<K, V> — альтернатива объекту с сохранением порядка
  • Set<T> — для уникальных значений
  • Tuple — кортежи, полезны в задачах на возврат пары значений
  • null | undefined — обработка граничных случаев

Структуры данных, которые чаще всего встречаются

  • Массивы — основа основ. Двумерные массивы, сортировка, бинарный поиск
  • Хеш-таблицы — для быстрого поиска (задача Two Sum — классика)
  • Стек и очередь — для задач на скобки, BFS, DFS
  • Связные списки — reverse, merge, detect cycle
  • Деревья — бинарные, бинарные деревья поиска, обходы
  • Графы — обычно на собеседованиях уровня Senior

Не пытайтесь выучить всё сразу. Начните с массивов и хеш-таблиц — это покроет 70% задач уровня Easy и Medium.

Как настроить окружение для TypeScript на LeetCode

LeetCode из коробки поддерживает TypeScript. При выборе языка просто кликните "TypeScript" в дропдауне. Однако если вы хотите писать код локально и тестировать, вот минимальный набор:

npm init -y
npm install typescript @types/node --save-dev
npx tsc --init

Создайте файл solution.ts и запускайте компиляцию командой npx tsc solution.ts && node solution.js. Это поможет вам привыкнуть к строгой типизации и отлавливать ошибки на лету.

Разбор 3 задач на TypeScript: от Easy до Hard

Теперь перейдём к практике. Я выбрал три задачи, которые отлично демонстрируют возможности TypeScript и часто встречаются на собеседованиях.

1. Two Sum (Easy) — классика жанра

Задача: дан массив чисел и цель. Нужно найти два числа, сумма которых равна цели, и вернуть их индексы.

function twoSum(nums: number[], target: number): number[] {
    const map = new Map<number, number>();

    for (let i = 0; i < nums.length; i++) {
        const complement = target - nums[i];
        if (map.has(complement)) {
            return [map.get(complement)!, i];
        }
        map.set(nums[i], i);
    }

    return [];
}

Разбор: Используем Map<number, number> — это типизированная хеш-таблица. Ключ — значение элемента, значение — его индекс. Оператор ! после map.get(complement) — это non-null assertion. Мы уверены, что значение есть, потому что проверили через has. Без него TypeScript ругался бы на возможный undefined.

Временная сложность: O(n), память: O(n). Это оптимальное решение.

2. Valid Parentheses (Medium) — работа со стеком

Задача: дана строка, содержащая скобки (), [], {}. Нужно проверить, корректно ли они закрыты.

function isValid(s: string): boolean {
    const stack: string[] = [];
    const map: Record<string, string> = {
        ')': '(',
        ']': '[',
        '}': '{'
    };

    for (const char of s) {
        if (char in map) {
            const top = stack.pop() || '#';
            if (top !== map[char]) return false;
        } else {
            stack.push(char);
        }
    }

    return stack.length === 0;
}

Разбор: Используем Record<string, string> для маппинга закрывающих скобок на открывающие. Стек хранит только открывающие скобки. Если встречаем закрывающую — проверяем, совпадает ли верхушка стека с ожидаемой парой. Если нет — строка невалидна.

Тип Record<string, string> — это встроенный утилитарный тип TypeScript, который создаёт объект с динамическими ключами. Он идеально подходит для таких словарей.

Временная сложность: O(n), память: O(n) в худшем случае (если все скобки открывающие).

3. Binary Tree Maximum Path Sum (Hard) — рекурсия с типами

Задача: найти максимальную сумму пути в бинарном дереве. Путь может начинаться и заканчиваться в любых узлах.

class TreeNode {
    val: number;
    left: TreeNode | null;
    right: TreeNode | null;
    constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
        this.val = (val === undefined ? 0 : val);
        this.left = (left === undefined ? null : left);
        this.right = (right === undefined ? null : right);
    }
}

function maxPathSum(root: TreeNode | null): number {
    let maxSum = -Infinity;

    function dfs(node: TreeNode | null): number {
        if (node === null) return                

Блоги

Рекомендаций по книгам