diff --git a/README.md b/README.md index 0002a6a..d878fa0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,30 @@ -# PHP_2026 +# Задание 18: IS/hw18 -https://otus.ru/lessons/razrabotchik-php/?utm_source=github&utm_medium=free&utm_campaign=otus +## Общее описание + +```text +Leetcode практикум +``` + +## Алгоритмическая сложность + +### 160. Intersection of Two Linked Lists + +```text +leetcode_160.php +Сложность в худшем случае O(n*m), т.к происходит полный перебор списка B на каждый элемент списка A, где n длинна списка A, m длинна списка B. +``` + +### 160. Intersection of Two Linked Lists (вариант с двумя указателями) + +```text +leetcode_160_2.php +Сложность O(n+m) и O(1), два указателя идут по спискам, при достижении конца переходят на начало другого - сходятся в точке пересечения ©. +``` + +### 166. Fraction to Recurring Decimal + +```text +leetcode_166.php +Сложность O(1), т.к все операции имеют сложность O(1). +``` \ No newline at end of file diff --git a/leetcode_160.php b/leetcode_160.php new file mode 100644 index 0000000..da484ab --- /dev/null +++ b/leetcode_160.php @@ -0,0 +1,83 @@ +val = $val; + } +} + + +class Solution +{ + /** + * @param ListNode $headA + * @param ListNode $headB + * @return ListNode + */ + function getIntersectionNode($headA, $headB): ?ListNode + { + if (is_null($headA)) return null; + $headBCopy = $headB; + while (!is_null($headBCopy)) { + if ($headA === $headBCopy) return $headA; + $headBCopy = $headBCopy->next; + } + + return $this->getIntersectionNode($headA->next, $headB); + } +} + +$solution = new Solution; +// example 1 +$intersectionList = new ListNode(8); +$intersectionList->next = new ListNode(4); +$intersectionList->next->next = new ListNode(5); + +// $listA = [4, 1, 8, 4, 5]; +$headA = new ListNode(4); +$headA->next = new ListNode(1); +$headA->next->next = $intersectionList; + +// $listB = [5, 6, 1, 8, 4, 5]; +$headB = new ListNode(5); +$headB->next = new ListNode(6); +$headB->next->next = new ListNode(1); +$headB->next->next->next = $intersectionList; + +$intersected = $solution->getIntersectionNode($headA, $headB); +echo ($intersected->val ?? 'No intersection') . PHP_EOL; + +// example 2 +$intersectionList = new ListNode(2); +$intersectionList->next = new ListNode(4); + +// $listA = [1,9,1,2,4]; +$headA = new ListNode(1); +$headA->next = new ListNode(9); +$headA->next->next = new ListNode(1); +$headA->next->next->next = $intersectionList; + +// listB = [3,2,4] +$headB = new ListNode(3); +$headB->next = $intersectionList; + +$intersected = $solution->getIntersectionNode($headA, $headB); +echo ($intersected->val ?? 'No intersection') . PHP_EOL; + + +// example 3 +// listA = [2,6,4] +$headA = new ListNode(2); +$headA->next = new ListNode(6); +$headA->next->next = new ListNode(4); + +// listB = [1,5] +$headB = new ListNode(1); +$headB->next = new ListNode(6); + +$intersected = $solution->getIntersectionNode($headA, $headB); +echo ($intersected->val ?? 'No intersection') . PHP_EOL; diff --git a/leetcode_160_2.php b/leetcode_160_2.php new file mode 100644 index 0000000..fd1cb83 --- /dev/null +++ b/leetcode_160_2.php @@ -0,0 +1,85 @@ +val = $val; + } +} + + +class Solution +{ + /** + * @param ListNode $headA + * @param ListNode $headB + * @return ListNode + */ + function getIntersectionNode($headA, $headB): ?ListNode + { + $currentA = $headA; + $currentB = $headB; + + while ($currentA !== $currentB) { + $currentA = $currentA == null ? $headB : $currentA->next; + $currentB = $currentB == null ? $headA : $currentB->next; + } + + return $currentA; + } +} + +$solution = new Solution; +// example 1 +$intersectionList = new ListNode(8); +$intersectionList->next = new ListNode(4); +$intersectionList->next->next = new ListNode(5); + +// $listA = [4, 1, 8, 4, 5]; +$headA = new ListNode(4); +$headA->next = new ListNode(1); +$headA->next->next = $intersectionList; + +// $listB = [5, 6, 1, 8, 4, 5]; +$headB = new ListNode(5); +$headB->next = new ListNode(6); +$headB->next->next = new ListNode(1); +$headB->next->next->next = $intersectionList; + +$intersected = $solution->getIntersectionNode($headA, $headB); +echo ($intersected->val ?? 'No intersection') . PHP_EOL; + +// example 2 +$intersectionList = new ListNode(2); +$intersectionList->next = new ListNode(4); + +// $listA = [1,9,1,2,4]; +$headA = new ListNode(1); +$headA->next = new ListNode(9); +$headA->next->next = new ListNode(1); +$headA->next->next->next = $intersectionList; + +// listB = [3,2,4] +$headB = new ListNode(3); +$headB->next = $intersectionList; + +$intersected = $solution->getIntersectionNode($headA, $headB); +echo ($intersected->val ?? 'No intersection') . PHP_EOL; + + +// example 3 +// listA = [2,6,4] +$headA = new ListNode(2); +$headA->next = new ListNode(6); +$headA->next->next = new ListNode(4); + +// listB = [1,5] +$headB = new ListNode(1); +$headB->next = new ListNode(5); +$headA->next->next = new ListNode(7); + +$intersected = $solution->getIntersectionNode($headA, $headB); +echo ($intersected->val ?? 'No intersection') . PHP_EOL; diff --git a/leetcode_166.php b/leetcode_166.php new file mode 100644 index 0000000..b8c69e3 --- /dev/null +++ b/leetcode_166.php @@ -0,0 +1,92 @@ + 0 && $denominator < 0) || ($numerator < 0 && $denominator > 0)) { + $result = '-'; + $numerator = abs($numerator); + $denominator = abs($denominator); + } + + // Получаем целую часть + $result .= intdiv($numerator, $denominator); + + // Если остатка от отделения нет, то возвращаем результат + if (($numerator % $denominator) === 0) { + return $result; + } + + $result .= '.'; + $hash = []; + $numerator = $numerator % $denominator; + while (true) { + $numerator = (int)($numerator * 10); + + // Если делитель начинает повторяться, записываем дробь с периодом и выходим из цикла + if (isset($hash[$numerator])) { + $result .= '(' . implode('', $hash) . ')'; + break; + } + $hash[$numerator] = intdiv($numerator, $denominator); + $numerator = $numerator % $denominator; + + // Если деление закончилось без остаткка, то записываем результат в дробную часть и выходим из цикла + if ($numerator === 0) { + $result .= implode('', $hash); + break; + } + } + + return $result; + } +} + +$solution = new Solution; +// Example 1: +// Input: numerator = 1, denominator = 2 +$result = $solution->fractionToDecimal(1, 2); +echo $result . PHP_EOL; +// Output: "0.5" + + +// Example 2: +// Input: numerator = 2, denominator = 1 +$result = $solution->fractionToDecimal(2, 1); +echo $result . PHP_EOL; +// Output: "2" + + +// Example 3: +// Input: numerator = 4, denominator = 333 +$result = $solution->fractionToDecimal(4, 333); +echo $result . PHP_EOL; +// Output: "0.(012)" + +// Example 4: +// Input: numerator = 22, denominator = 7 +$result = $solution->fractionToDecimal(22, 7); +echo $result . PHP_EOL; +// Output: "3.(142857)" + +// Example 5: +// Input: numerator = -1, denominator = -2 +$result = $solution->fractionToDecimal(-1, -2); +echo $result . PHP_EOL; +// Output: "0.5" + +// Example 6: +// Input: numerator = 1, denominator = 97 +$result = $solution->fractionToDecimal(1, 97); +echo $result . PHP_EOL; +// Output: "0.5" \ No newline at end of file diff --git a/lesson_28.php b/lesson_28.php new file mode 100644 index 0000000..d9e8a5e --- /dev/null +++ b/lesson_28.php @@ -0,0 +1,156 @@ + $maxElementInTail ? $head : $maxElementInTail; +// } + + +// // $max = findMax([1, 4, 2, 6, 6]); +// // echo $max; + +// function getLength(string $str): int +// { +// // Базовый случай: строка пустая +// if ($str === '') { +// return 0; +// } + +// // Рекурсивный случай +// $head = $str[0]; // "Отрываем голову" у строки +// $tail = substr($str, 1); // В $tail остаётся "хвост" + +// // Шаг рекурсии: вычисляем длину остатка строки... +// $tailLength = getLength($tail); + +// // todo Допишите недостающий код +// return 1 + $tailLength; +// } + +// // $len = getLength('vavavav'); +// // echo $len; + + +// function sumDigits(int $num): int +// { +// $lastDigitOfNum = $num % 10; // 1024 -> 4 5 -> 5 +// $numWithoutLastDigit = intdiv($num, 10); // 1024 -> 102 5 -> 0 + +// // todo: Базовый случай +// if ($numWithoutLastDigit === 0) return 0; + +// // todo: Шаг рекурсии +// return $lastDigitOfNum + sumDigits($numWithoutLastDigit); +// } + +// // $sum = sumDigits(1024); +// // echo $sum; + + +class TreeNode +{ + function __construct( + public int $val = 0, + public ?TreeNode $left = null, + public ?TreeNode $right = null + ) { + } +} + +function sum(?TreeNode $node): int +{ + // Базовый случай: узел равен NULL + if ($node === null) { + return 0; + } + + // Шаг рекурсии: вычисляем суммы поддеревьев... + $leftSum = sum($node->left); + $rightSum = sum($node->right); + + // ...и складываем их с текущим узлом + return $node->val + + $leftSum + + $rightSum; +} + +function checkTree(?TreeNode $root): bool +{ + $sum = sum($root); + + // return $root->val === (sum($root->left) + sum($root->right)); + return $sum / $root->val === 2; +} + + + +// class TreeNode +// { +// function __construct( +// public int $val = 0, +// public ?TreeNode $left = null, +// public ?TreeNode $right = null +// ) { +// } +// } + +// function maxDepth(?TreeNode $root): int +// { +// // Базовый случай: узел равен NULL +// if ($root === null) { +// return 0; +// } + +// // Шаг рекурсии: вычисляем глубину для каждого из поддеревьев... +// $leftDepth = maxDepth($root->left); +// $rightDepth = maxDepth($root->right); + +// // ...смотрим, какое из поддеревьев "глубже"... +// $maxDepth = max($leftDepth, $rightDepth); + +// return $maxDepth + 1; +// } + + +// class TreeNode +// { +// function __construct( +// public int|string $val, +// public ?TreeNode $left = null, +// public ?TreeNode $right = null +// ) {} +// } + +// function evaluate(TreeNode $root): int +// { +// // todo Граничный случай (узел содержит число) +// if (is_numeric($root->val)) { +// return $root->val; +// } + +// // todo Шаг рекурсии (узел содержит операцию '+' или '*', которую нужно применить к двум поддеревьям) +// if ($root->val === '+') { +// return evaluate($root->left) + evaluate($root->right); +// } + +// if ($root->val === '*') { +// return evaluate($root->left) * evaluate($root->right); +// } + +// return throw new \InvalidArgumentException('Не корректное значение узла'); +// }