PHP на LeetCode: неожиданный, но мощный инструмент
Когда слышишь «LeetCode», первая ассоциация — это Java, Python или C++. Но не спешите закрывать вкладку. PHP — это не только про веб-формы и WordPress. Современный PHP (начиная с 7 и 8 версий) — это полноценный язык для решения алгоритмических задач. Он быстр, лаконичен, а его встроенные функции для работы с массивами и строками могут дать фору многим «классическим» языкам.
В этой статье мы разберем, как решать задачи на LeetCode на PHP, какие структуры данных и алгоритмы стоит изучить, и покажем реальные примеры кода. Вы узнаете, почему PHP — это не «баг», а фича для собеседований, и как превратить рутину в увлекательный квест.
Почему стоит решать LeetCode на PHP?
Многие думают, что PHP не подходит для алгоритмов. Это миф. Вот три причины, почему PHP — отличный выбор:
- Богатая стандартная библиотека:
array_map,array_filter,array_reduce,explode— это готовые кирпичики для 80% задач. - Гибкая типизация: Вы можете быстро переключаться между строками, числами и массивами без лишнего бойлерплейта.
- Скорость: PHP 8 с JIT-компиляцией показывает результаты, сопоставимые с Python, а иногда и быстрее.
Кроме того, если вы PHP-разработчик, решение задач на LeetCode напрямую прокачивает ваше логическое мышление и понимание языка. Вы начинаете видеть неочевидные возможности array_* функций и учитесь писать эффективный, чистый код.
Что нужно изучить перед стартом
Прежде чем нырять в пул задач, убедитесь, что у вас есть база. Вот список тем, которые чаще всего встречаются в задачах LeetCode для PHP:
1. Массивы и хеш-таблицы
Это основа основ. 90% задач можно решить, умело манипулируя массивами. В PHP массивы — это одновременно и список, и словарь. Это даёт суперсилу: вы можете использовать array_key_exists для O(1) проверки наличия элемента.
Что изучить:
array_count_values— подсчёт частоты элементов.array_flip— обмен ключей и значений (полезно для поиска дубликатов).array_unique,array_diff,array_intersect.- Итерация с сохранением индекса:
foreach ($arr as $key => $value).
2. Строки
PHP исторически силён в работе со строками. Функции str_split, substr, strpos и str_replace — ваши лучшие друзья. Для задач на палиндромы, анаграммы или подсчёт символов они незаменимы.
Совет: Используйте strlen() для длины строки и mb_strlen() для мультибайтовых (Unicode).
3. Связанные списки и деревья
Здесь PHP немного уступает Java/C++, потому что нет встроенных классов для узлов. Но создавать свои классы — это просто и полезно. Вы поймёте, как работают ссылки и рекурсия.
Паттерн:
class ListNode {
public $val;
public $next;
public function __construct($val = 0, $next = null) {
$this->val = $val;
$this->next = $next;
}
}
4. Стек и очередь
В PHP нет отдельного класса Stack, но массив отлично справляется: array_push() / array_pop() для стека, array_shift() / array_push() для очереди. Для задач на валидацию скобок или BFS этого достаточно.
5. Сортировка и поиск
Встроенная sort() использует быструю сортировку и работает очень быстро. Для кастомных условий — usort() с callback-функцией. Знание бинарного поиска (вручную или через array_search в отсортированном массиве) — must-have.
Разбор реальных задач с кодом
Теперь перейдём к практике. Разберём три классические задачи с LeetCode разного уровня сложности. Все примеры на PHP.
Задача 1: Two Sum (Лёгкая)
Условие: Дан массив чисел и целевая сумма. Найдите два числа, которые в сумме дают цель. Верните их индексы.
Решение за O(n) с хеш-таблицей:
function twoSum($nums, $target) {
$map = []; // ключ — число, значение — его индекс
foreach ($nums as $i => $num) {
$complement = $target - $num;
if (array_key_exists($complement, $map)) {
return [$map[$complement], $i];
}
$map[$num] = $i;
}
return [];
}
// Пример:
$result = twoSum([2, 7, 11, 15], 9);
print_r($result); // [0, 1]
Почему это круто на PHP: Используем обычный массив как HashMap. array_key_exists работает за O(1). Код читается как поэзия.
Задача 2: Valid Parentheses (Средняя)
Условие: Дана строка, содержащая скобки (){}[]. Проверьте, корректно ли они закрыты и вложены.
Решение со стеком:
function isValid($s) {
$stack = [];
$map = [
')' => '(',
'}' => '{',
']' => '['
];
for ($i = 0; $i < strlen($s); $i++) {
$char = $s[$i];
if (in_array($char, ['(', '{', '['])) {
array_push($stack, $char);
} else {
if (empty($stack) || array_pop($stack) !== $map[$char]) {
return false;
}
}
}
return empty($stack);
}
// Пример:
echo isValid("()[]{}") ? "true" : "false"; // true
Фишка PHP: Используем in_array для проверки открывающих скобок. Код компактный и понятный.
Задача 3: Merge Two Sorted Lists (Средняя)
Условие: Даны два отсортированных связанных списка. Объедините их в один отсортированный список.
Решение с рекурсией:
class ListNode {
public $val;
public $next;
public function __construct($val = 0, $next = null) {
$this->val = $val