PHP | LeetCode

channel icon
Сайт: easyoffer.ru

Условия размещения

Цена за 48 часов в ленте 450,00
Цена за 1 час закрепления N/A
Взаимопиар Нет
Дополнительные условия рекламы Отсутствуют
0
1 291
подписчиков
0
179
охват 1 публикации
0
~2
постов / день
+0,0%
13,9%
ERR % ?

Статистика

Последние публикации

PHP | LeetCode
14 ноября 2024 г. 19:07
#medium
Задача: 237. Delete Node in a Linked List

Дан односвязный список с головой head, и требуется удалить узел node в этом списке.

Вам дан узел node, который нужно удалить. У вас нет доступа к первому узлу head.

Все значения в односвязном списке уникальны, и гарантируется, что данный узел node не является последним узлом в списке.

Удалите данный узел. Обратите внимание, что под удалением узла мы не подразумеваем его удаление из памяти. Мы имеем в виду:

- Значение данного узла не должно существовать в односвязном списке.
- Количество узлов в односвязном списке должно уменьшиться на один.
- Все значения перед узлом должны оставаться в том же порядке.
- Все значения после узла должны оставаться в том же порядке.

Пример:
Input: head = [4,5,1,9], node = 5
Output: [4,1,9]
Explanation: You are given the second node with value 5, the linked list should become 4 -> 1 -> 9 after calling your function.


👨‍💻 Алгоритм:

1⃣Копирование данных: Скопируйте значение из следующего узла (node.next) в текущий узел (node). Таким образом, текущий узел будет иметь значение, которое было в следующем узле.

2⃣Обновление указателя: Обновите указатель next текущего узла, чтобы он ссылался на узел, следующий за узлом node.next. Это effectively удалит следующий узел из списка.

3⃣Удаление ссылки на следующий узел: Убедитесь, что следующий узел больше не ссылается на другие узлы, тем самым полностью исключая его из списка.

😎 Решение:
class Solution {
function deleteNode($node) {
$node->val = $node->next->val;
$node->next = $node->next->next;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
14 ноября 2024 г. 12:07
#hard
Задача: 381. Insert Delete GetRandom O(1) - Duplicates allowed

RandomizedCollection — это структура данных, содержащая набор чисел, возможно с дубликатами (т.е. мультимножество). Она должна поддерживать вставку и удаление определенных элементов, а также предоставление случайного элемента.

Реализуйте класс RandomizedCollection:

RandomizedCollection(): Инициализирует пустой объект RandomizedCollection.
bool insert(int val): Вставляет элемент val в мультимножество, даже если элемент уже присутствует. Возвращает true, если элемента не было, и false в противном случае.
bool remove(int val): Удаляет элемент val из мультимножества, если он присутствует. Возвращает true, если элемент присутствовал, и false в противном случае. Если у val несколько вхождений в мультимножестве, удаляется только одно из них.
int getRandom(): Возвращает случайный элемент из текущего мультимножества. Вероятность возврата каждого элемента пропорциональна числу вхождений этого элемента в мультимножество.
Реализуйте функции класса так, чтобы каждая функция работала в среднем за O(1) времени.

Пример:
Input
["RandomizedCollection", "insert", "insert", "insert", "getRandom", "remove", "getRandom"]
[[], [1], [1], [2], [], [1], []]
Output
[null, true, false, true, 2, true, 1]


👨‍💻 Алгоритм:

1⃣Создать словарь для хранения значений и их индексов в списке, а также список для хранения всех элементов мультимножества.

2⃣Метод insert(val): Добавить значение в конец списка и обновить словарь, добавив индекс этого значения. Возвращать true, если значение отсутствовало ранее, и false в противном случае.
Метод remove(val): Удалить одно вхождение значения из словаря и списка. Для удаления значения заменить его последним элементом списка и обновить словарь. Возвращать true, если значение присутствовало, и false в противном случае.

3⃣Метод getRandom(): Возвращать случайный элемент из списка, обеспечивая равновероятное распределение на основе количества вхождений каждого элемента.

😎 Решение:
class RandomizedCollection {
private $dict;
private $list;

function __construct() {
$this->dict = [];
$this->list = [];
}

function insert($val) {
$exists = isset($this->dict[$val]);
if (!$exists) {
$this->dict[$val] = [];
}
$this->dict[$val][] = count($this->list);
$this->list[] = $val;
return !$exists;
}

function remove($val) {
if (!isset($this->dict[$val]) || count($this->dict[$val]) === 0) {
return false;
}
$index = array_pop($this->dict[$val]);
$lastElement = array_pop($this->list);
if ($index < count($this->list)) {
$this->list[$index] = $lastElement;
$this->dict[$lastElement][array_search(count($this->list), $this->dict[$lastElement])] = $index;
}
if (count($this->dict[$val]) === 0) {
unset($this->dict[$val]);
}
return true;
}

function getRandom() {
return $this->list[array_rand($this->list)];
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
13 ноября 2024 г. 19:07
#medium
Задача: 339. Nested List Weight Sum

Вам дан вложенный список целых чисел nestedList. Каждый элемент либо целое число, либо список, элементы которого также могут быть целыми числами или другими списками.

Глубина целого числа — это количество списков, в которых оно находится. Например, вложенный список [1,[2,2],[[3],2],1] имеет значения каждого целого числа, установленные в его глубину.

Верните сумму каждого целого числа в nestedList, умноженного на его глубину.

Пример:
Input: nestedList = [1,[4,[6]]]
Output: 27
Explanation: One 1 at depth 1, one 4 at depth 2, and one 6 at depth 3. 1*1 + 4*2 + 6*3 = 27.


👨‍💻 Алгоритм:

1⃣ Инициализация и вызов рекурсивной функции:
Создайте основную функцию, которая принимает вложенный список и вызывает вспомогательную рекурсивную функцию с начальной глубиной 1.

2⃣ Рекурсивное исследование списка:
В вспомогательной функции пройдите по каждому элементу списка. Если элемент является целым числом, добавьте его значение, умноженное на текущую глубину, к общей сумме. Если элемент является списком, вызовите вспомогательную функцию рекурсивно с увеличенной глубиной.

3⃣ Возврат результата:
Возвращайте общую сумму на каждом уровне рекурсии. Основная функция возвращает итоговую сумму.

😎 Решение:
class Solution {
function depthSum($nestedList) {
return $this->dfs($nestedList, 1);
}

private function dfs($list, $depth) {
$total = 0;
foreach ($list as $nested) {
if ($nested->isInteger()) {
$total += $nested->getInteger() * $depth;
} else {
$total += $this->dfs($nested->getList(), $depth + 1);
}
}
return $total;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
13 ноября 2024 г. 12:07
#medium
Задача: 380. Insert Delete GetRandom O(1)

Реализуйте класс RandomizedSet:

RandomizedSet(): Инициализирует объект RandomizedSet.
bool insert(int val): Вставляет элемент val в множество, если его там нет. Возвращает true, если элемент отсутствовал, и false в противном случае.
bool remove(int val): Удаляет элемент val из множества, если он присутствует. Возвращает true, если элемент присутствовал, и false в противном случае.
int getRandom(): Возвращает случайный элемент из текущего множества элементов (гарантируется, что по крайней мере один элемент существует при вызове этого метода). Каждый элемент должен иметь равную вероятность быть возвращенным.
Вы должны реализовать функции класса таким образом, чтобы каждая функция работала в среднем за O(1) по времени.

Пример:
Input
["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
[[], [1], [2], [2], [], [1], [2], []]
Output
[null, true, false, true, 2, true, false, 2]


👨‍💻 Алгоритм:

1⃣Создать словарь для хранения значений и их индексов, а также список для хранения значений.

2⃣Метод insert(val): Проверить наличие значения в словаре. Если отсутствует, добавить значение в список и обновить словарь с новым индексом.
Метод remove(val): Проверить наличие значения в словаре. Если присутствует, заменить удаляемое значение последним элементом списка, обновить его индекс в словаре, удалить последний элемент из списка и удалить значение из словаря.

3⃣Метод getRandom(): Возвращать случайный элемент из списка, используя встроенную функцию генерации случайных чисел.

😎 Решение:
class RandomizedSet {
private $dict;
private $list;

function __construct() {
$this->dict = [];
$this->list = [];
}

function insert($val) {
if (array_key_exists($val, $this->dict)) {
return false;
}
$this->dict[$val] = count($this->list);
$this->list[] = $val;
return true;
}

function remove($val) {
if (!array_key_exists($val, $this->dict)) {
return false;
}
$index = $this->dict[$val];
$lastElement = array_pop($this->list);
if ($index < count($this->list)) {
$this->list[$index] = $lastElement;
$this->dict[$lastElement] = $index;
}
unset($this->dict[$val]);
return true;
}

function getRandom() {
return $this->list[array_rand($this->list)];
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
12 ноября 2024 г. 19:07
Задача: 236. Lowest Common Ancestor of a Binary Tree

Дано бинарное дерево. Найдите наименьший общий предок (LCA) двух заданных узлов в дереве.

Согласно определению LCA на Википедии: "Наименьший общий предок определяется между двумя узлами p и q как наименьший узел в дереве T, который имеет как p, так и q в качестве потомков (где мы допускаем, что узел может быть потомком самого себя)."

Пример:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.


👨‍💻 Алгоритм:

1⃣Начало обхода дерева с корня: Начните обход дерева с корневого узла. Если текущий узел является одним из узлов p или q, установите переменную mid в значение True и продолжите поиск другого узла в левой и правой ветвях.

2⃣Проверка поддеревьев: Выполните рекурсивный обход левой и правой ветвей дерева. Если какая-либо из ветвей (левая или правая) возвращает True, это означает, что один из двух узлов найден ниже по дереву.

3⃣Определение LCA: Если в любой момент обхода дерева две из трех переменных (left, right или mid) становятся True, это означает, что найден наименьший общий предок (LCA) для узлов p и q.

😎 Решение:
class Solution {
private $ans;

function __construct() {
$this->ans = null;
}

private function recurseTree($currentNode, $p, $q) {
if ($currentNode === null) {
return false;
}

$left = $this->recurseTree($currentNode->left, $p, $q) ? 1 : 0;
$right = $this->recurseTree($currentNode->right, $p, $q) ? 1 : 0;
$mid = ($currentNode === $p || $currentNode === $q) ? 1 : 0;

if ($mid + $left + $right >= 2) {
$this->ans = $currentNode;
}

return ($mid + $left + $right > 0);
}

function lowestCommonAncestor($root, $p, $q) {
$this->recurseTree($root, $p, $q);
return $this->ans;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
12 ноября 2024 г. 12:07
#medium
Задача: 379. Design Phone Directory

Создайте телефонный справочник, который изначально имеет maxNumbers пустых слотов для хранения номеров. Справочник должен хранить номера, проверять, пуст ли определенный слот, и освобождать данный слот.

Реализуйте класс PhoneDirectory:

PhoneDirectory(int maxNumbers) Инициализирует телефонный справочник с количеством доступных слотов maxNumbers.
int get() Предоставляет номер, который никому не назначен. Возвращает -1, если номера недоступны.
bool check(int number) Возвращает true, если слот доступен, и false в противном случае.
void release(int number) Перераспределяет или освобождает номер слота.

Пример:
Input
["PhoneDirectory", "get", "get", "check", "get", "check", "release", "check"]
[[3], [], [], [2], [], [2], [2], [2]]
Output
[null, 0, 1, true, 2, false, null, true]


👨‍💻 Алгоритм:

1⃣Инициализировать массив isSlotAvailable размером maxNumbers, установив значение true во всех индексах.

2⃣Метод get(): Проходить по массиву isSlotAvailable. Если найдется true на каком-либо индексе, установить isSlotAvailable[i] = false и вернуть i. Если доступных слотов нет, вернуть -1.
Метод check(number): Вернуть значение isSlotAvailable[number].

3⃣Метод release(number): Установить isSlotAvailable[number] = true.

😎 Решение:
class PhoneDirectory {
private $isSlotAvailable;

function __construct($maxNumbers) {
$this->isSlotAvailable = array_fill(0, $maxNumbers, true);
}

function get() {
for ($i = 0; $i < count($this->isSlotAvailable); $i++) {
if ($this->isSlotAvailable[$i]) {
$this->isSlotAvailable[$i] = false;
return $i;
}
}
return -1;
}

function check($number) {
return $this->isSlotAvailable[$number];
}

function release($number) {
$this->isSlotAvailable[$number] = true;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
12 ноября 2024 г. 10:35
Репост:
Твое резюме на HeadHunter — ОК, если ты видишь это.

HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.

Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.

Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.

Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.

О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
PHP | LeetCode
11 ноября 2024 г. 19:07
#medium
Задача: 235. Lowest Common Ancestor of a Binary Search Tree

Дано бинарное дерево поиска (BST). Найдите наименьший общий предок (LCA) двух заданных узлов в BST.

Согласно определению LCA на Википедии: "Наименьший общий предок определяется между двумя узлами p и q как наименьший узел в дереве T, который имеет как p, так и q в качестве потомков (где мы допускаем, что узел может быть потомком самого себя)."

Пример:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.


👨‍💻 Алгоритм:

1⃣Начало обхода дерева с корня: Начните обход дерева с корневого узла. Проверьте, находятся ли узлы p и q в правом или левом поддереве текущего узла.

2⃣Продолжение поиска в поддереве: Если оба узла p и q находятся в правом поддереве текущего узла, продолжайте поиск в правом поддереве, начиная с шага 1. Если оба узла p и q находятся в левом поддереве текущего узла, продолжайте поиск в левом поддереве, начиная с шага 1.

3⃣Нахождение LCA: Если узлы p и q находятся в разных поддеревьях относительно текущего узла или один из узлов равен текущему узлу, то текущий узел является наименьшим общим предком (LCA). Верните этот узел как результат.

😎 Решение:
class Solution {
function lowestCommonAncestor($root, $p, $q) {
$parentVal = $root->val;
$pVal = $p->val;
$qVal = $q->val;

if ($pVal > $parentVal && $qVal > $parentVal) {
return $this->lowestCommonAncestor($root->right, $p, $q);
} else if ($pVal < $parentVal && $qVal < $parentVal) {
return $this->lowestCommonAncestor($root->left, $p, $q);
} else {
return $root;
}
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
11 ноября 2024 г. 12:07
#medium
Задача: 378. Kth Smallest Element in a Sorted Matrix

Дана матрица размером n x n, где каждая строка и каждый столбец отсортированы в порядке возрастания. Верните k-й наименьший элемент в матрице.

Заметьте, что это k-й наименьший элемент в отсортированном порядке, а не k-й уникальный элемент.

Вы должны найти решение с использованием памяти лучше, чем O(n²).

Пример:
Input: matrix = [[-5]], k = 1
Output: -5


👨‍💻 Алгоритм:

1⃣Инициализировать мин-кучу H. В нашем решении мы будем рассматривать каждую строку как отдельный список. Поскольку столбцы также отсортированы, мы можем рассматривать каждый столбец как отдельный список.

2⃣Взять первые элементы из min(N, K) строк, где N представляет количество строк, и добавить каждый из этих элементов в кучу. Важно знать, к какой строке и столбцу принадлежит элемент, чтобы в дальнейшем перемещаться по соответствующему списку.

3⃣Мин-куча будет содержать тройки информации (значение, строка, столбец). Куча будет упорядочена по значениям, и мы будем использовать номера строк и столбцов для добавления следующего элемента, если текущий элемент будет удален из кучи.

😎 Решение:
class Solution {
private function dfs($word, $length, &$visited, $dictionary) {
if ($length == strlen($word)) {
return true;
}
if ($visited[$length]) {
return false;
}
$visited[$length] = true;
for ($i = strlen($word) - ($length == 0 ? 1 : 0); $i > $length; $i--) {
if (isset($dictionary[substr($word, $length, $i - $length)]) &&
$this->dfs($word, $i, $visited, $dictionary)) {
return true;
}
}
return false;
}

function findAllConcatenatedWordsInADict($words) {
$dictionary = array_flip($words);
$answer = [];
foreach ($words as $word) {
$visited = array_fill(0, strlen($word), false);
if ($this->dfs($word, 0, $visited, $dictionary)) {
$answer[] = $word;
}
}
return $answer;
}
}

$solution = new Solution();
$words = ["cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"];
print_r($solution->findAllConcatenatedWordsInADict($words));


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
10 ноября 2024 г. 19:07
#hard
Задача: 472. Concatenated Words

Дан массив строк words (без дубликатов). Верните все составные слова из данного списка слов.

Составное слово определяется как строка, которая полностью состоит как минимум из двух более коротких слов (не обязательно различных) из данного массива.

Пример:
Input: words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
Output: ["catsdogcats","dogcatsdog","ratcatdogcat"]
Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats";
"dogcatsdog" can be concatenated by "dog", "cats" and "dog";
"ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".


👨‍💻 Алгоритм:

1⃣Для каждого слова в списке:
Построить неявный граф, в котором узлы представляют индексы символов в слове, а ребра представляют возможность перехода от одного индекса к другому, если подстрока между ними является словом из списка.

2⃣Использовать поиск в глубину (DFS) для проверки, можно ли достигнуть узел с индексом word.length от узла с индексом 0 в графе.

3⃣Если узел word.length достижим от узла 0, добавить слово в ответ.

😎 Решение:
class Solution {
private function dfs($word, $length, &$visited, $dictionary) {
if ($length == strlen($word)) {
return true;
}
if ($visited[$length]) {
return false;
}
$visited[$length] = true;
for ($i = strlen($word) - ($length == 0 ? 1 : 0); $i > $length; $i--) {
if (isset($dictionary[substr($word, $length, $i - $length)]) &&
$this->dfs($word, $i, $visited, $dictionary)) {
return true;
}
}
return false;
}

function findAllConcatenatedWordsInADict($words) {
$dictionary = array_flip($words);
$answer = [];
foreach ($words as $word) {
$visited = array_fill(0, strlen($word), false);
if ($this->dfs($word, 0, $visited, $dictionary)) {
$answer[] = $word;
}
}
return $answer;
}
}

// Example usage
$solution = new Solution();
$words = ["cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"];
print_r($solution->findAllConcatenatedWordsInADict($words));


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
10 ноября 2024 г. 12:07
#medium
Задача: 470. Implement Rand10() Using Rand7()

Дано API rand7(), которое генерирует случайное целое число в диапазоне [1, 7]. Напишите функцию rand10(), которая генерирует случайное целое число в диапазоне [1, 10]. Вы можете вызывать только API rand7(), и не должны вызывать другие API. Пожалуйста, не используйте встроенные в язык функции для генерации случайных чисел.

Каждый тестовый случай будет содержать один внутренний аргумент n, который указывает количество вызовов вашей реализованной функции rand10() во время тестирования. Обратите внимание, что это не аргумент, передаваемый в rand10().

Пример:
Input: n = 1
Output: [2]


😎 Решение:
class Solution {
public function rand10() {
do {
$row = rand7();
$col = rand7();
$idx = $col + ($row - 1) * 7;
} while ($idx > 40);
return 1 + ($idx - 1) % 10;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
10 ноября 2024 г. 10:10
Бесплатное IT-образование в 2024

Отобрали для вас полезные телеграм-каналы, которые помогут освоить программирование и другие IT-направления

Выбирайте нужное и подписывайтесь:

👩‍💻 Python: @PythonPortal
📱 GitHub: @git_developer
👩‍💻 Frontend: @FrontendPortal
🤓 Книги айти: @portalToIT
👩‍💻 Java: @Java_Iibrary
👩‍💻 C#: @KodBlog
👩‍💻 С/С++: @Cpportal
⚙️ Backend: @BackendPortal
🐞 Тестирование: @QAPortal
👩‍💻 DevOps: @loose_code
🖥 Базы Данных & SQL: @SQL
👩‍💻 Golang: @juniorGolang
👩‍💻 PHP: @PHPortal
👩‍💻 Моб. разработка: @MobDev
👩‍💻 Разработка игр: @GameDevgx
🖥 Data Science: @DataSciencegx
🤔 Хакинг & ИБ: @cybersecinform
📱 Маркетинг: @MarketingPortal
🖥 Дизайн: @PortalToDesign

➡️ Сохраняйте себе, чтобы не потерять
PHP | LeetCode
9 ноября 2024 г. 19:07
#easy
Задача: 338. Counting Bits

Дано целое число n, верните массив ans длиной n + 1, такой что для каждого i (0 <= i <= n), ans[i] будет равняться количеству единиц в двоичном представлении числа i.

Пример:
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101


👨‍💻 Алгоритм:

1⃣Инициализация массива:
Создайте массив ans длиной n + 1, заполненный нулями. Этот массив будет содержать количество единиц в двоичном представлении каждого числа от 0 до n.

2⃣Итерация и вычисление:
Пройдите в цикле по всем числам от 1 до n. Для каждого числа x используйте битовую операцию x & (x - 1), чтобы убрать последнюю установленную биту, и добавьте 1 к значению ans для этого результата. Это количество единиц в двоичном представлении числа x.

3⃣Возврат результата:
Верните заполненный массив ans, который содержит количество единиц для каждого числа от 0 до n.

😎 Решение:
class Solution {
function countBits($num) {
$ans = array_fill(0, $num + 1, 0);
for ($x = 1; $x <= $num; $x++) {
$ans[$x] = $ans[$x & ($x - 1)] + 1;
}
return $ans;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
9 ноября 2024 г. 12:07
#medium
Задача: 468. Validate IP Address

Допустимый IPv4-адрес — это IP в форме "x1.x2.x3.x4", где 0 <= xi <= 255 и xi не может содержать ведущие нули. Например, "192.168.1.1" и "192.168.1.0" являются допустимыми IPv4-адресами, тогда как "192.168.01.1", "192.168.1.00" и "192.168@1.1" являются недопустимыми IPv4-адресами.

Допустимый IPv6-адрес — это IP в форме "x1:x2:x3:x4:x5:x6:x7
", где:
1 <= xi.length <= 4
xi — это шестнадцатеричная строка, которая может содержать цифры, строчные английские буквы ('a' до 'f') и прописные английские буквы ('A' до 'F').
Ведущие нули в xi допускаются.

Пример:
Input: queryIP = "172.16.254.1"
Output: "IPv4"
Explanation: This is a valid IPv4 address, return "IPv4".


👨‍💻 Алгоритм:

1⃣Для проверки адреса IPv4:
Разделить IP на четыре части по разделителю ".".
Проверить каждую подстроку:
Является ли она целым числом между 0 и 255.
Не содержит ли она ведущих нулей (исключение — число "0").

2⃣Для проверки адреса IPv6:
Разделить IP на восемь частей по разделителю ":".
Проверить каждую подстроку:
Является ли она шестнадцатеричным числом длиной от 1 до 4 символов.

3⃣Если IP не соответствует ни одному из форматов, вернуть "Neither".

😎 Решение:
class Solution {
public function validateIPv4($IP) {
$nums = explode('.', $IP);
if (count($nums) != 4) return "Neither";
foreach ($nums as $x) {
if (strlen($x) == 0 || strlen($x) > 3) return "Neither";
if ($x[0] == '0' && strlen($x) != 1) return "Neither";
if (!ctype_digit($x)) return "Neither";
if (intval($x) > 255) return "Neither";
}
return "IPv4";
}

public function validateIPv6($IP) {
$nums = explode(':', $IP);
$hexdigits = "0123456789abcdefABCDEF";
if (count($nums) != 8) return "Neither";
foreach ($nums as $x) {
if (strlen($x) == 0 || strlen($x) > 4) return "Neither";
for ($i = 0; $i < strlen($x); $i++) {
if (strpos($hexdigits, $x[$i]) === false) return "Neither";
}
}
return "IPv6";
}

public function validIPAddress($IP) {
if (substr_count($IP, '.') == 3) {
return $this->validateIPv4($IP);
} elseif (substr_count($IP, ':') == 7) {
return $this->validateIPv6($IP);
} else {
return "Neither";
}
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
8 ноября 2024 г. 19:07
#medium
Задача: 337. House Robber III

Вор снова нашел себе новое место для краж. В этом районе есть только один вход, который называется корнем.
Кроме корня, каждый дом имеет только один родительский дом. После осмотра, умный вор понял, что все дома в этом месте образуют бинарное дерево. Полиция будет автоматически уведомлена, если два дома, напрямую связанные между собой, будут ограблены в одну ночь.

Дано корневое дерево бинарного дерева, верните максимальную сумму денег, которую вор может украсть, не уведомляя полицию.

Пример:
Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.


👨‍💻 Алгоритм:

1⃣Инициализация и базовый случай:
Создайте вспомогательную функцию helper, которая принимает узел в качестве входных данных и возвращает массив из двух элементов, где первый элемент представляет максимальную сумму денег, которую можно украсть, если не грабить этот узел, а второй элемент - если грабить этот узел.
Базовый случай для вспомогательной функции - узел null, и в этом случае функция возвращает массив из двух нулей [0, 0].

2⃣Рекурсивное исследование дерева:
В функции helper вызывайте её рекурсивно для левого и правого поддеревьев текущего узла.
Если грабить текущий узел, то нельзя грабить его потомков, поэтому сумма будет равна значению текущего узла плюс максимальные суммы для случаев, когда потомки не грабятся.
Если не грабить текущий узел, то можно свободно выбирать, грабить потомков или нет, поэтому сумма будет равна максимальной сумме из двух вариантов для каждого потомка.

3⃣Возврат результата:
В основной функции rob вызовите helper для корня дерева и верните максимальное значение из двух элементов массива, возвращенного функцией helper.

😎 Решение:
class TreeNode {
public $val;
public $left;
public $right;
function __construct($val = 0, $left = null, $right = null) {
$this->val = $val;
$this->left = $left;
$this->right = $right;
}
}

class Solution {
function rob($root) {
$answer = $this->helper($root);
return max($answer[0], $answer[1]);
}

function helper($node) {
if ($node === null) {
return [0, 0];
}

$left = $this->helper($node->left);
$right = $this->helper($node->right);

$rob = $node->val + $left[1] + $right[1];
$notRob = max($left[0], $left[1]) + max($right[0], $right[1]);

return [$rob, $notRob];
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
8 ноября 2024 г. 12:07
#medium
Задача: 465. Optimal Account Balancing

Дан массив транзакций transactions, где transactions[i] = [fromi, toi, amounti] указывает на то, что человек с ID = fromi дал сумму amounti долларов человеку с ID = toi.

Верните минимальное количество транзакций, необходимых для урегулирования долгов.

Пример:
Input: transactions = [[0,1,10],[2,0,5]]
Output: 2


👨‍💻 Алгоритм:

1⃣Создать хеш-таблицу для хранения чистого баланса каждого человека.

2⃣Собрать все ненулевые чистые балансы в массив balance_list.

3⃣Определить рекурсивную функцию dfs(cur) для очистки всех балансов в диапазоне balance_list[0 ~ cur]:
Игнорировать cur, если баланс уже равен 0. Пока balance_list[cur] = 0, переходить к следующему человеку, увеличивая cur на 1.
Если cur = n, вернуть 0.
В противном случае установить cost на большое значение, например, inf.
Пройтись по индексу nxt от cur + 1, если balance_list[nxt] * balance_list[cur] < 0,
Добавить баланс balance_list[cur] к balance_list[nxt]: balance_list[nxt] += balance_list[cur].
Рекурсивно вызвать dfs(cur + 1) как dfs(cur) = 1 + dfs(cur + 1).
Убрать ранее переданный баланс от cur: balance_list[nxt] -= balance_list[cur] (откат).
Повторить с шага 5 и отслеживать минимальное количество операций cost = min(cost, 1 + dfs(cur + 1)), найденных в итерации.
Вернуть cost, когда итерация завершена. Вернуть dfs(0).

😎 Решение:
class Solution {
private $creditList;

function minTransfers($transactions) {
$creditMap = [];
foreach ($transactions as $t) {
if (!isset($creditMap[$t[0]])) $creditMap[$t[0]] = 0;
if (!isset($creditMap[$t[1]])) $creditMap[$t[1]] = 0;
$creditMap[$t[0]] += $t[2];
$creditMap[$t[1]] -= $t[2];
}

$this->creditList = [];
foreach ($creditMap as $amount) {
if ($amount != 0) {
$this->creditList[] = $amount;
}
}

$n = count($this->creditList);
return $this->dfs(0, $n);
}

private function dfs($cur, $n) {
while ($cur < $n && $this->creditList[$cur] == 0) {
$cur++;
}

if ($cur == $n) {
return 0;
}

$cost = PHP_INT_MAX;
for ($nxt = $cur + 1; $nxt < $n; $nxt++) {
if ($this->creditList[$nxt] * $this->creditList[$cur] < 0) {
$this->creditList[$nxt] += $this->creditList[$cur];
$cost = min($cost, 1 + $this->dfs($cur + 1, $n));
$this->creditList[$nxt] -= $this->creditList[$cur];
}
}

return $cost;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
7 ноября 2024 г. 19:07
#hard
Задача: 336. Palindrome Pairs

Вам дан массив уникальных строк words, индексируемый с 0.

Пара палиндромов — это пара целых чисел (i, j), таких что:
0 <= i, j < words.length,
i != j, и
words[i] + words[j] (конкатенация двух строк) является палиндромом.
Верните массив всех пар палиндромов из слов.

Вы должны написать алгоритм с временной сложностью O(сумма длин всех слов в words).

Пример:
Input: words = ["abcd","dcba","lls","s","sssll"]
Output: [[0,1],[1,0],[3,2],[2,4]]
Explanation: The palindromes are ["abcddcba","dcbaabcd","slls","llssssll"]


👨‍💻 Алгоритм:

1⃣Инициализация и подготовка данных:
Создайте структуру для хранения результатов (список пар индексов).
Создайте словарь для хранения слов и их индексов, чтобы ускорить поиск.

2⃣Итерация по всем парам слов и проверка:
Пройдите по всем парам слов в массиве words, используя два вложенных цикла.
Для каждой пары слов проверяйте, образуют ли они палиндром при конкатенации. Это делается путем объединения строк и проверки, равна ли объединенная строка своей обратной версии.

3⃣Добавление найденных пар в результат:
Если проверка на палиндром проходит, добавьте текущую пару индексов в список результатов.
Верните итоговый список всех найденных пар.

😎 Решение:
class Solution {
/**
* @param String[] $words
* @return Integer[][]
*/
function palindromePairs($words) {
$pairs = [];

for ($i = 0; $i < count($words); $i++) {
for ($j = 0; $j < count($words); $j++) {
if ($i == $j) continue;
$combined = $words[$i] . $words[$j];
if ($combined == strrev($combined)) {
$pairs[] = [$i, $j];
}
}
}

return $pairs;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
7 ноября 2024 г. 12:07
#medium
Задача: 377. Combination Sum IV

Дан массив различных целых чисел nums и целое число target. Верните количество возможных комбинаций, которые в сумме дают target.

Тестовые случаи сгенерированы так, что ответ помещается в 32-битное целое число.

Пример:
Input: nums = [9], target = 3
Output: 0


👨‍💻 Алгоритм:

1⃣В этом подходе мы начнем со стратегии сверху вниз, которая, пожалуй, более интуитивна. Как следует из названия, стратегия сверху вниз начинается с исходных данных, и затем мы рекурсивно уменьшаем входные данные до меньшего масштаба, пока не достигнем уровней, которые больше невозможно разбить.

2⃣Из-за рекурсивной природы формулы мы можем напрямую перевести формулу в рекурсивную функцию.

3⃣Здесь, соответственно, мы определяем рекурсивную функцию под названием combs(remain), которая возвращает количество комбинаций, где каждая комбинация в сумме дает значение remain.

😎 Решение:
class Solution {
private $memo = [];

public function combinationSum4($nums, $target) {
return $this->combs($nums, $target);
}

private function combs($nums, $remain) {
if ($remain == 0) {
return 1;
}
if (isset($this->memo[$remain])) {
return $this->memo[$remain];
}

$result = 0;
foreach ($nums as $num) {
if ($remain - $num >= 0) {
$result += $this->combs($nums, $remain - $num);
}
}
$this->memo[$remain] = $result;
return $result;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
6 ноября 2024 г. 19:07
#easy
Задача: 463. Island Perimeter

Дан массив размером row x col, представляющий карту, где grid[i][j] = 1 обозначает сушу, а grid[i][j] = 0 обозначает воду.

Клетки сетки соединены горизонтально/вертикально (не по диагонали). Сетка полностью окружена водой, и на ней находится ровно один остров (т.е. одна или более соединённых ячеек суши).

У острова нет "озёр", то есть вода внутри не соединена с водой вокруг острова. Одна ячейка - это квадрат со стороной 1. Сетка прямоугольная, ширина и высота не превышают 100. Определите периметр острова.

Пример:
Input: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
Output: 16
Explanation: The perimeter is the 16 yellow stripes in the image above.

👨‍💻 Алгоритм:

1⃣Пройти через каждую ячейку сетки и, когда вы находитесь в ячейке с значением 1 (ячейка суши), проверить окружающие (СВЕРХУ, СПРАВА, СНИЗУ, СЛЕВА) ячейки.

2⃣Ячейка суши без каких-либо окружающих ячеек суши будет иметь периметр 4. Вычесть 1 за каждую окружающую ячейку суши.

3⃣Когда вы находитесь в ячейке с значением 0 (ячейка воды), ничего не делать. Просто перейти к следующей ячейке.

😎 Решение:
class Solution {
public function islandPerimeter($grid) {
$rows = count($grid);
$cols = count($grid[0]);

$result = 0;

for ($r = 0; $r < $rows; $r++) {
for ($c = 0; $c < $cols; $c++) {
if ($grid[$r][$c] == 1) {
$up = ($r == 0) ? 0 : $grid[$r-1][$c];
$left = ($c == 0) ? 0 : $grid[$r][$c-1];
$down = ($r == $rows-1) ? 0 : $grid[$r+1][$c];
$right = ($c == $cols-1) ? 0 : $grid[$r][$c+1];

$result += 4 - ($up + $left + $right + $down);
}
}
}

return $result;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний
PHP | LeetCode
6 ноября 2024 г. 12:07
#easy
Задача: 376. Wiggle Subsequence

Колеблющаяся последовательность — это последовательность, в которой разности между последовательными числами строго чередуются между положительными и отрицательными. Первая разность (если она существует) может быть как положительной, так и отрицательной. Последовательность с одним элементом и последовательность с двумя неравными элементами тривиально являются колеблющимися последовательностями.

Например, [1, 7, 4, 9, 2, 5] — это колеблющаяся последовательность, потому что разности (6, -3, 5, -7, 3) чередуются между положительными и отрицательными.
В отличие от нее, [1, 4, 7, 2, 5] и [1, 7, 4, 5, 5] не являются колеблющимися последовательностями. Первая не является, потому что первые две разности положительные, а вторая не является, потому что последняя разность равна нулю.
Подпоследовательность получается путем удаления некоторых элементов (возможно, нуля) из исходной последовательности с сохранением оставшихся элементов в их первоначальном порядке.

Дан целочисленный массив nums, верните длину самой длинной колеблющейся подпоследовательности из nums.

Пример:
Input: nums = [1,7,4,9,2,5]
Output: 6
Explanation: The entire sequence is a wiggle sequence with differences (6, -3, 5, -7, 3).


👨‍💻 Алгоритм:

1⃣Для понимания этого подхода создайте два массива для динамического программирования, названных up и down. Эти массивы будут хранить длины наибольших колеблющихся подпоследовательностей, заканчивающихся соответственно восходящим или нисходящим колебанием.

2⃣up[i] относится к длине самой длинной колеблющейся подпоследовательности на данный момент, если рассматривать i-й элемент как последний элемент последовательности, заканчивающейся восходящим колебанием. Аналогично, down[i] относится к длине самой длинной колеблющейся подпоследовательности, если рассматривать i-й элемент как последний элемент последовательности, заканчивающейся нисходящим колебанием.

3⃣up[i] обновляется каждый раз, когда мы находим восходящее колебание, заканчивающееся на i-м элементе. Чтобы найти up[i], необходимо учесть максимальное значение всех предыдущих подпоследовательностей, заканчивающихся нисходящим колебанием, т.е. down[j], для каждого j<i и nums[i]>nums[j]. Аналогично, down[i] обновляется при нахождении нисходящего колебания.

😎 Решение:
class Solution {
public function islandPerimeter($grid) {
$rows = count($grid);
$cols = count($grid[0]);

$result = 0;

for ($r = 0; $r < $rows; $r++) {
for ($c = 0; $c < $cols; $c++) {
if ($grid[$r][$c] == 1) {
$up = ($r == 0) ? 0 : $grid[$r-1][$c];
$left = ($c == 0) ? 0 : $grid[$r][$c-1];
$down = ($r == $rows-1) ? 0 : $grid[$r+1][$c];
$right = ($c == $cols-1) ? 0 : $grid[$r][$c+1];

$result += 4 - ($up + $left + $right + $down);
}
}
}

return $result;
}
}


Ставь 👍👍 и забирай 📚 📚 Базу знанийБазу знаний