BACK TO BLOG

Мой неожиданный фейл с LinkedList

В LeetCode есть ряд задач типа «Design a data structure» (622. Design Circular Queue, 706. Design HashMap и т. д.).

Пока готовилась к собесам, решала подобные задачи и получалось укладываться в свои 45 минут. Пока не попробовала решить 707. Design LinkedList.

Основной код я набросала примерно за минут 20, уверенно жму «Submit» и… фейл. Тесты не прошли. Поправила и теперь падает на других кейсах. Проходит час. Потом полтора. Нервничаю, начинаю путаться. Понимаю, что если бы это был настоящий собес, то давно бы завалила. Паника. В итоге только спустя 2,5 часа я смогла наконец-то засабмитить рабочее решение.

Как так?! Всего-то нужно было написать несколько методов для linkedlist. Теорию я вроде прочитала, поняла. Это ведь не деревья или графы. Должно быть тривиальным.

Позже, когда я начала читать разборы и смотреть комментарии, оказалось, я не одна. И есть статистика, которая это подтверждает.

У LeetCode есть метрика под названием Acceptance rate. Это процент правильных ответов от общего числа попыток.

705. Design HashSet: 67.3%

622. Design Circular Queue: 53.0%

706. Design HashMap: 66.1%

225. Implement Stack using Queues: 68.3%

641. Design Circular Deque: 64.4%

355. Design Twitter: 43.4% (задача на системный дизайн)

А теперь как думаете, сколько у 707. Design Linked List?

29.4%!

Почему?

Причина 1. Нужно вручную управлять указателями next (иногда и prev), и очень легко ошибиться.

Причина 2. Edge cases есть в каждом методе, иногда по несколько.

Причина 3. Разная логика проверки индексов в разных методах.

Причина 4. Нужны нестандартные виды обхода linked list: indexed, penultimate и sentinel-based (для оптимизации).

Причина 5. Если что-то забыть, то linked list не бросает exception, а ведёт себя неожиданно, усложняя отладку.

Всё это похоже на поход по минному полю: забыли обновить один pointer и всё сломалось, не продумали edge case и взрыв.

Что помогло?

1. Разделила задачу на маленькие логические части.

2. Взяла бумагу и карандаш: рисовала и проверяла каждый шаг алгоритма.

3. Продумала основные edge cases: пустой список, один элемент и полный список.

4. Только потом приступила к коду.

5. Не торопилась, фокусировалась на закреплении.

В задачах на linked list дольше рисуешь, чем кодируешь.

Совет

Для начала хорошо овладейте вот этими техниками для singly и doubly linked list:

1. Indexed и penultimate traversal

2. Insert at head/tail

3. Insert between

4. Delete head/tail и delete between

Начать можно с этих задач:

Особенно важна логика проверки edge cases в этих техниках.

После всех этих шагов, дней через 3–4, я снова попробовала решить 707 и на этот раз справилась за 28 минут. Хоть я и удовлетворена, но претензии всё ещё остались. Кто вообще дал право Linked List, ещё и линейной структуре, меня так мучать?

Не дайте Linked List вас травмировать. Освойте паттерны и техники и берегите своё ментальное здоровье.

Автор:

Айдана Нурланова

LinkedIn Instagram Telegram