Необходимо объединить два отсортированных связанных списка в один. Новый список должен быть составлен путем связывания узлов двух исходных списков.
Пакет доступен на Packagist и устанавливается через Composer:
composer require evgeny87/leetcode-taskПри реализации были соблюдены следующие стандарты:
- Immutability: Сервис объявлен как
final readonly(стандарт PHP 8.4+). - DI & Clean Code: Строгое соблюдение PSR-12, использование Constructor Injection и отказ от статических методов.
- Алгоритмические "Три кита":
- Использование указателей для навигации.
- Чистые условные выражения без оператора "!".
- Цикл
whileдля итерации по связанным спискам.
leetcode-task/
├── src/
│ ├── Service/
│ │ └── MergeService.php # Бизнес-логика (слияние двумя методами)
│ ├── DTO/
│ │ └── ListNode.php # Объект данных (узлы списка)
│ └── Exceptions/
│ └── ListEmptyException.php # Кастомные ошибки
├── README.md # Документация и анализ с описание и обоснование сложности
└── composer.json # Автозагрузка PSR-4
-
Вариант In-Place (Алгоритмический)
- Сложность по времени (T): O(n + m), где n и m — количество узлов в списках. Мы совершаем один линейный проход по элементам (слайды 10, 43).
- Сложность по памяти (M): O(1). Алгоритм не выделяет память под новые элементы, работая исключительно с перестановкой указателей существующих объектов в памяти (splicing).
-
Вариант Immutable (Архитектурный)
- Сложность по времени (T): O(n + m). Аналогичный линейный проход.
- Сложность по памяти (M): O(n + m). Алгоритм создает полностью новые объекты ListNode для результирующего списка.
В данной работе реализовано два подхода для демонстрации понимания различных сценариев разработки:
- Демонстрация эффективности (In-Place): Этот метод ориентирован на максимальную производительность и минимальное потребление ресурсов. Он идеально подходит для алгоритмических соревнований (LeetCode), где критичны лимиты памяти.
- Демонстрация чистоты архитектуры (Immutable): Этот метод следует принципу No Side Effects. В реальных энтерпрайз-системах (The evgeny87 Way) важно, чтобы входные данные оставались неизменными. Использование Immutable-подхода гарантирует, что исходные списки не будут "испорчены" в процессе слияния, что предотвращает трудноуловимые баги в других частях системы, которые могут использовать те же объекты.