PHP | LeetCode
1.49K subscribers
179 photos
1.1K links
Cайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp

Тесты t.me/+pSDoLEZBQRZlNmFi
Вопросы собесов t.me/+RJaDhjYaQDo2Njcy
Вакансии t.me/+J-DKRUtjUgMxZGNi
Download Telegram
Задача: 951. Flip Equivalent Binary Trees
Сложность: medium

Для бинарного дерева T мы можем определить операцию переворота следующим образом: выбираем любой узел и меняем местами левое и правое дочерние поддеревья. Бинарное дерево X эквивалентно бинарному дереву Y тогда и только тогда, когда мы можем сделать X равным Y после некоторого количества операций переворота. Учитывая корни двух бинарных деревьев root1 и root2, верните true, если эти два дерева эквивалентны перевороту, или false в противном случае.

Пример:
Input: root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 = [1,3,2,null,6,4,5,null,null,null,null,8,7]
Output: true


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

1⃣Если оба дерева пусты, они эквивалентны, вернуть true. Если одно дерево пустое, а другое нет, они не эквивалентны, вернуть false.

2⃣Если значения корней деревьев не совпадают, вернуть false.
Проверить два условия:
Левое поддерево первого дерева эквивалентно левому поддереву второго дерева и правое поддерево первого дерева эквивалентно правому поддереву второго дерева.
Левое поддерево первого дерева эквивалентно правому поддереву второго дерева и правое поддерево первого дерева эквивалентно левому поддереву второго дерева.

3⃣Вернуть true, если выполняется хотя бы одно из этих условий.

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

function flipEquiv($root1, $root2) {
if ($root1 == null && $root2 == null) return true;
if ($root1 == null || $root2 == null) return false;
if ($root1->val != $root2->val) return false;

return (flipEquiv($root1->left, $root2->left) && flipEquiv($root1->right, $root2->right)) ||
(flipEquiv($root1->left, $root2->right) && flipEquiv($root1->right, $root2->left));
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Когда проекты растут, а требований становится больше, скорость разработки начинает упираться не в язык или фреймворки, а в процессы, инструменты и организацию работы.

С 1 по 5 декабря конференция Podlodka PHP Crew собирает сезон о том, как разгонять PHP-разработку без стресса и перегрузов.

📌 В программу вошли новые доклады:

🧩 Тесты для ускорения — Александр Макаров (Twindo): о роли тестирования в скорости разработки, какие виды тестов действительно дают ускорение, и как распределить ответственность между разработчиками, QA и LLM.

📄 Контракты пишем — код генерим — Александр Забанов (Вебпрактик): contract-first подход, который снижает количество ошибок и делает интеграции предсказуемыми.

🧱 Платформа как LEGO — Антон Комарев (BelkaCar): как собрать внутреннюю платформу для разработчиков из готовых «кубиков» и убрать хаос внутренних тулов.

🎛 Фича-флаги — Сергей Волошин (Вебпрактик): как перейти от «деплой = релиз» к гибкому управлению функциональностью и выпускать код хоть каждый час.

💡Все темы прикладные, с упором на ускорение команд и уменьшение рутины.

🔗 Программа и билеты: https://podlodka.io/phpcrew
Когда проекты растут, а требований становится больше, скорость разработки начинает упираться не в язык или фреймворки, а в процессы, инструменты и организацию работы.

С 1 по 5 декабря конференция Podlodka PHP Crew собирает сезон о том, как разгонять PHP-разработку без стресса и перегрузов.

📌 В программу вошли новые доклады:

🧩 Тесты для ускорения — Александр Макаров (Twindo): о роли тестирования в скорости разработки, какие виды тестов действительно дают ускорение, и как распределить ответственность между разработчиками, QA и LLM.

📄 Контракты пишем — код генерим — Александр Забанов (Вебпрактик): contract-first подход, который снижает количество ошибок и делает интеграции предсказуемыми.

🧱 Платформа как LEGO — Антон Комарев (BelkaCar): как собрать внутреннюю платформу для разработчиков из готовых «кубиков» и убрать хаос внутренних тулов.

🎛 Фича-флаги — Сергей Волошин (Вебпрактик): как перейти от «деплой = релиз» к гибкому управлению функциональностью и выпускать код хоть каждый час.

💡Все темы прикладные, с упором на ускорение команд и уменьшение рутины.

🔗 Программа и билеты: https://podlodka.io/phpcrew
Задача: 1518. Water Bottles
Сложность: easy

У вас есть numBottles полных бутылок воды. За каждые numExchange пустых бутылок можно получить одну полную. Посчитайте, сколько всего бутылок воды можно выпить, если каждый раз менять пустые на новые.

Пример:
Input: numBottles = 9, numExchange = 3
Output: 13
Explanation: You can exchange 3 empty bottles to get 1 full water bottle.
Number of water bottles you can drink: 9 + 3 + 1 = 13.


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

1⃣Инициализируйте переменную ответа consumedBottles значением 0.

2⃣Продолжайте выполнять следующие действия, пока количество numBottles больше или равно numExchange: Выпейте numExchange количество полных бутылок, т.е. добавьте numExchange к consumedBottles. Уменьшите numExchange от доступных полных бутылок numBottles. Обменяйте пустые бутылки на одну полную бутылку, т.е. увеличьте numBottles на одну.

3⃣Верните consumedBottles + numBottles.

😎 Решение:
class Solution {
function numWaterBottles($numBottles, $numExchange) {
$consumedBottles = 0;

while ($numBottles >= $numExchange) {
$consumedBottles += $numExchange;
$numBottles -= $numExchange;
$numBottles++;
}

return $consumedBottles + $numBottles;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 900. RLE Iterator
Сложность: medium

Для кодирования последовательности целых чисел мы можем использовать кодирование по длине строки (т. е. RLE). В кодированном по длине пробега массиве четной длины (с индексацией 0) для всех четных i значение encoding[i] говорит нам о том, сколько раз неотрицательное целое значение encoding[i + 1] повторяется в последовательности.

Например, последовательность arr = [8,8,8,5,5] может быть закодирована как encoding = [3,8,2,5]. encoding = [3,8,0,9,2,5] и encoding = [2,8,1,8,2,5] также являются допустимыми RLE для arr.
Задав кодированный по длине пробега массив, разработайте итератор для его итерации. Реализуйте класс RLEIterator: RLEIterator(int[] encoded) Инициализирует объект с кодированным массивом encoded. int next(int n) Исчерпывает следующие n элементов и возвращает последний исчерпанный таким образом элемент. Если не осталось элементов для исчерпания, возвращает -1.

Пример:
Input
["RLEIterator", "next", "next", "next", "next"]
[[[3, 8, 0, 9, 2, 5]], [2], [1], [1], [2]]
Output
[null, 8, 8, 5, -1]


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

1⃣Инициализировать итератор с закодированным массивом и индексом, указывающим на текущую позицию.

2⃣При вызове метода next(n), уменьшить текущий счетчик на n или перейти к следующему числу, если текущий счетчик равен нулю.

3⃣Возвращать текущий элемент или -1, если все элементы исчерпаны.

😎 Решение:
class RLEIterator {
private $encoding;
private $index;

function __construct($encoding) {
$this->encoding = $encoding;
$this->index = 0;
}

function next($n) {
while ($this->index < count($this->encoding)) {
if ($n > $this->encoding[$this->index]) {
$n -= $this->encoding[$this->index];
$this->index += 2;
} else {
$this->encoding[$this->index] -= $n;
return $this->encoding[$this->index + 1];
}
}
return -1;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 417. Pacific Atlantic Water Flow
Сложность: medium

Имеется прямоугольный остров размером m x n, который граничит с Тихим и Атлантическим океанами. Тихий океан касается левого и верхнего краев острова, а Атлантический океан - правого и нижнего краев. Остров разбит на сетку квадратных ячеек. Вам дана целочисленная матрица heights размером m x n, где heights[r][c] - высота над уровнем моря клетки с координатами (r, c). На острове выпадает много осадков, и дождевая вода может стекать в соседние клетки прямо на север, юг, восток и запад, если высота соседней клетки меньше или равна высоте текущей клетки. Вода может течь из любой клетки, прилегающей к океану, в океан. Верните двумерный список координат сетки result, где result[i] = [ri, ci] означает, что дождевая вода может течь из клетки (ri, ci) как в Тихий, так и в Атлантический океаны.

Пример:
Input: heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
Output: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]


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

1⃣Определите две матрицы для отслеживания клеток, из которых вода может течь в Тихий и Атлантический океаны, используя поиск в глубину (DFS) или поиск в ширину (BFS), начиная с границ, примыкающих к каждому океану.

2⃣Выполните поиск для каждого океана, обновляя матрицы достижимости.

3⃣Соберите координаты клеток, которые могут стекать в оба океана, проверяя пересечение двух матриц достижимости.

😎 Решение:
function pacificAtlantic($heights) {
$m = count($heights);
$n = count($heights[0]);
$pacific = array_fill(0, $m, array_fill(0, $n, false));
$atlantic = array_fill(0, $m, array_fill(0, $n, false));
$directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];

function dfs($r, $c, &$ocean, $heights, $directions) {
$ocean[$r][$c] = true;
foreach ($directions as [$dr, $dc]) {
$nr = $r + $dr;
$nc = $c + $dc;
if ($nr >= 0 && $nc >= 0 && $nr < count($heights) && $nc < count($heights[0]) && !$ocean[$nr][$nc] && $heights[$nr][$nc] >= $heights[$r][$c]) {
dfs($nr, $nc, $ocean, $heights, $directions);
}
}
}

for ($i = 0; $i < $m; $i++) {
dfs($i, 0, $pacific, $heights, $directions);
dfs($i, $n - 1, $atlantic, $heights, $directions);
}
for ($j = 0; $j < $n; $j++) {
dfs(0, $j, $pacific, $heights, $directions);
dfs($m - 1, $j, $atlantic, $heights, $directions);
}

$result = [];
for ($i = 0; $i < $m; $i++) {
for ($j = 0; $j < $n; $j++) {
if ($pacific[$i][$j] && $atlantic[$i][$j]) {
$result[] = [$i, $j];
}
}
}
return $result;
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1240. Tiling a Rectangle with the Fewest Squares
Сложность: hard

Если задан прямоугольник размером n x m, верните минимальное количество квадратов с целочисленными сторонами, которые покрывают этот прямоугольник.

Пример:
Input: n = 2, m = 3
Output: 3


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

1⃣Инициализация рекурсивной функции:
Функция принимает размеры прямоугольника n x m.

2⃣Базовый случай:
Если n = 0 или m = 0, возвращаем 0, так как не осталось пространства для покрытия.

3⃣Рекурсивный случай:
Находим наибольший возможный квадрат, который может быть размещен в текущем прямоугольнике. Это квадрат со стороной min(n, m).
Размещаем этот квадрат в левом верхнем углу и рекурсивно покрываем оставшиеся три части:
Прямоугольник слева от квадрата.
Прямоугольник сверху от квадрата.
Прямоугольник справа и снизу от квадрата.

😎 Решение:
function tilingRectangle($n, $m) {
$dp = array_fill(0, $n + 1, array_fill(0, $m + 1, PHP_INT_MAX));

for ($i = 1; $i <= min($n, $m); $i++) {
$dp[$i][$i] = 1;
}

for ($h = 1; $h <= $n; $h++) {
for ($w = 1; $w <= $m; $w++) {
if ($h == $w) continue;
for ($i = 1; $i <= intdiv($h, 2); $i++) {
$dp[$h][$w] = min($dp[$h][$w], $dp[$i][$w] + $dp[$h - $i][$w]);
}
for ($j = 1; $j <= intdiv($w, 2); $j++) {
$dp[$h][$w] = min($dp[$h][$w], $dp[$h][$j] + $dp[$h][$w - $j]);
}
}
}
return $dp[$n][$m];
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Задача: 895. Maximum Frequency Stack
Сложность: hard

Разработайте структуру данных, похожую на стек, чтобы заталкивать элементы в стек и вытаскивать из него самый частый элемент. Реализуйте класс FreqStack: FreqStack() строит пустой стек частот. void push(int val) заталкивает целое число val на вершину стека. int pop() удаляет и возвращает самый частый элемент в стеке. Если есть равенство в выборе самого частого элемента, то удаляется и возвращается элемент, который ближе всего к вершине стека.

Пример:
Input
["FreqStack", "push", "push", "push", "push", "push", "push", "pop", "pop", "pop", "pop"]
[[], [5], [7], [5], [7], [4], [5], [], [], [], []]
Output
[null, null, null, null, null, null, null, 5, 7, 5, 4]


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

1⃣Создать два словаря: freq для хранения частоты каждого элемента и group для хранения стека элементов для каждой частоты.

2⃣При добавлении элемента увеличивать его частоту в freq и добавлять его в стек соответствующей частоты в group.

3⃣При извлечении элемента найти максимальную частоту, удалить элемент из стека соответствующей частоты и уменьшить его частоту в freq. Если стек для данной частоты становится пустым, удалить его.

😎 Решение:
class FreqStack {
private $freq;
private $group;
private $maxfreq;

function __construct() {
$this->freq = [];
$this->group = [];
$this->maxfreq = 0;
}

function push($val) {
$f = ($this->freq[$val] ?? 0) + 1;
$this->freq[$val] = $f;
if ($f > $this->maxfreq) {
$this->maxfreq = $f;
$this->group[$f] = [];
}
$this->group[$f][] = $val;
}

function pop() {
$val = array_pop($this->group[$this->maxfreq]);
$this->freq[$val]--;
if (empty($this->group[$this->maxfreq])) {
$this->maxfreq--;
}
return $val;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 73. Set Matrix Zeroes
Сложность: medium

Дана матрица размером m×n, состоящая из целых чисел. Если элемент матрицы равен 0, установите в 0 все элементы его строки и столбца.

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

Пример:
Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]


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

1⃣Мы перебираем матрицу и отмечаем первую ячейку строки i и первую ячейку столбца j, если условие в приведенном выше псевдокоде выполняется, т.е. если cell[i][j] == 0.

2⃣Первая ячейка строки и столбца для первой строки и первого столбца совпадают, т.е. cell[0][0]. Поэтому мы используем дополнительную переменную, чтобы узнать, был ли отмечен первый столбец, а cell[0][0] используется для того же для первой строки.

3⃣Теперь мы перебираем исходную матрицу, начиная со второй строки и второго столбца, т.е. с matrix[1][1]. Для каждой ячейки мы проверяем, были ли ранее отмечены строка r или столбец c, проверяя соответствующую первую ячейку строки или первую ячейку столбца. Если любая из них была отмечена, мы устанавливаем значение в ячейке на 0. Обратите внимание, что первая строка и первый столбец служат как row_set и column_set, которые мы использовали в первом подходе. Затем мы проверяем, равна ли cell[0][0] нулю, если это так, мы отмечаем первую строку как ноль. И, наконец, если первый столбец был отмечен, мы делаем все записи в нем нулевыми.

😎 Решение:
function setZeroes(&$matrix) {
$isCol = false;
$R = count($matrix);
$C = count($matrix[0]);

for ($i = 0; $i < $R; $i++) {
if ($matrix[$i][0] == 0) {
$isCol = true;
}
for ($j = 1; $j < $C; $j++) {
if ($matrix[$i][$j] == 0) {
$matrix[0][$j] = 0;
$matrix[$i][0] = 0;
}
}
}

for ($i = 1; $i < $R; $i++) {
for ($j = 1; $j < $C; $j++) {
if ($matrix[$i][0] == 0 || $matrix[0][$j] == 0) {
$matrix[$i][$j] = 0;
}
}
}

if ($matrix[0][0] == 0) {
for ($j = 0; $j < $C; $j++) {
$matrix[0][$j] = 0;
}
}

if ($isCol) {
for ($i = 0; $i < $R; $i++) {
$matrix[$i][0] = 0;
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 46. Permutations
Сложность: medium

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

Пример:
Input: nums = [0,1]
Output: [[0,1],[1,0]]


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

1⃣Если длина curr равна длине nums, добавьте копию curr в ans и вернитесь.

2⃣Итерируйтесь по nums. Для каждого num, если num не в curr, выполните следующее:
Добавьте num в curr и вызовите backtrack(curr), затем удалите num из curr.

3⃣Вызовите backtrack с изначально пустым curr.
Верните ans.

😎 Решение:
function permute($nums) {
$ans = [];
$backtrack = function (&$curr) use (&$ans, &$backtrack, $nums) {
if (count($curr) === count($nums)) {
$ans[] = $curr;
return;
}
foreach ($nums as $num) {
if (!in_array($num, $curr)) {
$curr[] = $num;
$backtrack($curr);
array_pop($curr);
}
}
};
$backtrack([]);
return $ans;
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 299. Bulls and Cows
Сложность: medium

Вы играете в игру "Быки и коровы" со своим другом.
Вы записываете секретное число и просите своего друга угадать, что это за число. Когда ваш друг делает предположение, вы даете ему подсказку со следующей информацией:
Количество "быков", то есть цифры в предположении, которые находятся на правильной позиции.
Количество "коров", то есть цифры в предположении, которые есть в вашем секретном числе, но находятся на неправильной позиции. Конкретно, это не-бычьи цифры в предположении, которые можно переставить так, чтобы они стали быками.
Дано секретное число secret и предположение вашего друга guess, верните подсказку для предположения вашего друга.
Подсказка должна быть в формате "xAyB", где x — количество быков, а y — количество коров. Обратите внимание, что и secret, и guess могут содержать повторяющиеся цифры.

Пример:
Input: secret = "1807", guess = "7810"
Output: "1A3B"
Explanation: Bulls are connected with a '|' and cows are underlined:
"1807"
|
"7810"


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

1⃣Инициализация счетчиков:
Инициализируйте количество быков и коров значениями ноль.
Создайте хеш-таблицу для хранения символов строки secret и их частот.

2⃣Обход строки guess:
Для каждого символа ch в строке guess:
Если ch присутствует в строке secret:
Если текущий символ ch совпадает с символом на той же позиции в secret (ch == secret[idx]):
Увеличьте количество быков: bulls += 1.
Обновите количество коров, если количество текущего символа в хеш-таблице отрицательное или равно нулю (то есть этот символ уже использовался для коров): cows -= int(h[ch] <= 0).
Если текущий символ ch не совпадает с символом на той же позиции в secret (ch != secret[idx]):
Увеличьте количество коров, если количество текущего символа в хеш-таблице больше нуля: cows += int(h[ch] > 0).
Обновите хеш-таблицу, помечая текущий символ как использованный: h[ch] -= 1.

3⃣Возврат результата:
Верните количество быков и коров в формате "xAyB".

😎 Решение:
class Solution {
function getHint($secret, $guess) {
$h = [];
for ($i = 0; $i < strlen($secret); $i++) {
$ch = $secret[$i];
if (!isset($h[$ch])) {
$h[$ch] = 0;
}
$h[$ch]++;
}

$bulls = 0;
$cows = 0;
$n = strlen($guess);
$secretArray = str_split($secret);
$guessArray = str_split($guess);

for ($idx = 0; $idx < $n; $idx++) {
$ch = $guessArray[$idx];
if (isset($h[$ch])) {
if ($ch == $secretArray[$idx]) {
$bulls++;
if ($h[$ch] <= 0) {
$cows--;
}
} else {
if ($h[$ch] > 0) {
$cows++;
}
}
$h[$ch]--;
}
}

return "{$bulls}A{$cows}B";
}
}
?>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 142. Linked List Cycle II
Сложность: medium

Дана голова связного списка. Верните узел, с которого начинается цикл. Если цикла нет, верните null.
Цикл в связном списке существует, если есть такой узел в списке, до которого можно добраться снова, последовательно следуя по указателю next. Внутренне переменная pos используется для обозначения индекса узла, к которому подключен указатель next последнего узла (индексация с нуля). Она равна -1, если цикла нет. Обратите внимание, что pos не передается в качестве параметра.
Не модифицируйте связный список.

Пример:
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.


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

1⃣Инициализация и начало обхода:
Инициализируйте узел указателем на голову связного списка и создайте пустое множество nodes_seen для отслеживания посещенных узлов.
Начните обход со связного списка, перемещая узел на один шаг за раз.

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

3⃣Добавление узла в множество или завершение обхода:
Если узел не найден в nodes_seen, добавьте его в множество и перейдите к следующему узлу.
Если узел становится равным null (конец списка), верните null. В списке нет цикла, так как в случае наличия цикла вы бы застряли в петле и не достигли бы конца списка.

😎 Решение:
class ListNode {
public $val;
public $next;

public function __construct($val = 0, $next = null) {
$this->val = $val;
$this->next = $next;
}
}

function detectCycle($head) {
$nodesSeen = [];
$node = $head;
while ($node !== null) {
if (in_array($node, $nodesSeen, true)) {
return $node;
} else {
$nodesSeen[] = $node;
$node = $node->next;
}
}
return null;
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1180. Count Substrings with Only One Distinct Letter
Сложность: easy

Дана строка s. Верните количество подстрок, которые содержат только одну уникальную букву.

Пример:
Input: s = "aaaba"
Output: 8
Explanation: The substrings with one distinct letter are "aaa", "aa", "a", "b".
"aaa" occurs 1 time.
"aa" occurs 2 times.
"a" occurs 4 times.
"b" occurs 1 time.
So the answer is 1 + 2 + 4 + 1 = 8.


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

1⃣Инициализируйте целочисленную переменную total для подсчета количества подстрок, а также два указателя left и right, которые отмечают начало и конец подстроки, содержащей только одну уникальную букву.

2⃣Итерируйте по строке S: Если мы не достигли конца и новый символ S[right] такой же, как и начальный символ S[left], увеличьте right на 1 для дальнейшего исследования строки S; в противном случае вычислите длину подстроки как right - left и примените формулу суммы арифметической последовательности; не забудьте установить right в left для начала исследования новой подстроки.

3⃣После завершения итерации добавьте к total количество подстрок для последнего сегмента, если он не был учтен. Верните значение total.

😎 Решение:
class Solution {
function countLetters($S) {
$total = 0;
$left = 0;

for ($right = 0; $right <= strlen($S); $right++) {
if ($right == strlen($S) || $S[$left] != $S[$right]) {
$lenSubstring = $right - $left;
$total += (1 + $lenSubstring) * $lenSubstring / 2;
$left = $right;
}
}
return $total;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 686. Repeated String Match
Сложность: medium

Даны две строки a и b. Верните минимальное количество повторений строки a, чтобы строка b стала её подстрокой. Если сделать b подстрокой a невозможно, верните -1.

Обратите внимание: строка "abc", повторенная 0 раз, это "", повторенная 1 раз - "abc", повторенная 2 раза - "abcabc".

Пример:
Input: a = "abcd", b = "cdabcdab"
Output: 3
Explanation: We return 3 because by repeating a three times "abcdabcdabcd", b is a substring of it.


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

1⃣Найти минимальное количество повторений строки A, чтобы её длина стала больше или равна длине B. Это значение q = ceil(len(B) / len(A)).

2⃣Проверить, является ли B подстрокой строки A, повторенной q раз. Если да, вернуть q. Иначе, проверить строку A, повторенную (q+1) раз. Если B является подстрокой этой строки, вернуть q+1.

3⃣Если B не является подстрокой ни в одном из случаев, вернуть -1.

😎 Решение:
class Solution {
function repeatedStringMatch($A, $B) {
$q = 1;
$S = $A;
while (strlen($S) < strlen($B)) {
$S .= $A;
$q++;
}
if (strpos($S, $B) !== false) return $q;
if (strpos($S . $A, $B) !== false) return $q + 1;
return -1;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 468. Validate IP Address
Сложность: medium

Допустимый 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";
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 955. Delete Columns to Make Sorted II
Сложность: medium

Вам дан массив из n строк одинаковой длины. Мы можем выбрать любые индексы удаления и удалить все символы в этих индексах для каждой строки.

Например, если у нас есть strs = ["abcdef", "uvwxyz"] и индексы удаления {0, 2, 3}, то конечный массив после удаления будет ["bef", "vyz"]. Предположим, что мы выбрали набор индексов удаления answer таким образом, что после удаления конечный массив имеет элементы в лексикографическом порядке (т.е, strs[0] <= strs[1] <= strs[2] <= ... <= strs[n - 1]). Возвращает минимально возможное значение answer.length.

Пример:
Input: strs = ["ca","bb","ac"]
Output: 1


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

1⃣Определить количество строк n и длину каждой строки m.
Создать массив delete_count длиной m, который будет отслеживать количество удаляемых столбцов.

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

3⃣Повторять процесс до тех пор, пока массив строк не станет лексикографически отсортированным.
Вернуть количество удаленных столбцов.

😎 Решение:
function minDeletionSize($strs) {
$n = count($strs);
$m = strlen($strs[0]);
$deleteCount = array_fill(0, $m, false);

function isSorted($strs, $deleteCount) {
$n = count($strs);
$m = count($deleteCount);
for ($i = 0; $i < $n - 1; $i++) {
for ($j = 0; $j < $m; $j++) {
if ($deleteCount[$j]) continue;
if ($strs[$i][$j] > $strs[$i + 1][$j]) return false;
if ($strs[$i][$j] < $strs[$i + 1][$j]) break;
}
}
return true;
}

while (!isSorted($strs, $deleteCount)) {
for ($j = 0; $j < $m; $j++) {
if ($deleteCount[$j]) continue;
for ($i = 0; $i < $n - 1; $i++) {
if ($strs[$i][$j] > $strs[$i + 1][$j]) {
$deleteCount[$j] = true;
break;
}
}
if ($deleteCount[$j]) break;
}
}

return array_sum($deleteCount);
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1347. Minimum Number of Steps to Make Two Strings Anagram
Сложность: medium

Даны две строки одинаковой длины s и t. За один шаг вы можете выбрать любой символ строки t и заменить его другим символом.

Вернуть минимальное количество шагов, чтобы сделать t анаграммой строки s.

Анаграмма строки — это строка, которая содержит те же символы в другом (или том же) порядке.

Пример:
Input: s = "bab", t = "aba"
Output: 1
Explanation: Replace the first 'a' in t with b, t = "bba" which is anagram of s.


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

1⃣Вычислить разницу частот символов в строках t и s, сохраняя результаты в массиве count.

2⃣Подсчитать количество символов, которые нужно заменить в t, добавляя в ans только положительные значения из массива count.

3⃣Вернуть ans как минимальное количество шагов для превращения t в анаграмму строки s.

😎 Решение:
class Solution {
public function minSteps($s, $t) {
$count = array_fill(0, 26, 0);

for ($i = 0; $i < strlen($s); $i++) {
$count[ord($t[$i]) - ord('a')]++;
$count[ord($s[$i]) - ord('a')]--;
}

$ans = 0;
for ($i = 0; $i < 26; $i++) {
$ans += max(0, $count[$i]);
}

return $ans;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 949. Largest Time for Given Digits
Сложность: medium

Учитывая массив arr из 4 цифр, найдите самое позднее 24-часовое время, которое можно составить, используя каждую цифру ровно один раз. 24-часовое время имеет формат "ЧЧ:ММ", где ЧЧ - от 00 до 23, а ММ - от 00 до 59. Самое раннее 24-часовое время - 00:00, а самое позднее - 23:59. Верните самое позднее 24-часовое время в формате "HH:MM". Если не удается определить действительное время, возвращается пустая строка.

Пример:
Input: arr = [1,2,3,4]
Output: "23:41"


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

1⃣Перебрать все возможные перестановки массива arr.

2⃣Проверить каждую перестановку, можно ли из нее составить допустимое 24-часовое время.
Найти самое позднее допустимое время среди всех перестановок.

3⃣Алгоритм
Перебрать все возможные перестановки массива arr.
Проверить каждую перестановку, можно ли из нее составить допустимое 24-часовое время.
Найти самое позднее допустимое время среди всех перестановок.
Вернуть найденное время в формате "HH
". Если допустимое время не найдено, вернуть пустую строку.

😎 Решение:
function largestTimeFromDigits($arr) {
sort($arr);
$maxTime = -1;

do {
$hours = $arr[0] * 10 + $arr[1];
$minutes = $arr[2] * 10 + $arr[3];
if ($hours < 24 && $minutes < 60) {
$maxTime = max($maxTime, $hours * 60 + $minutes);
}
} while (next_permutation($arr));

if ($maxTime == -1) {
return "";
}

return sprintf("%02d:%02d", $maxTime / 60, $maxTime % 60);
}

function next_permutation(&$arr) {
$n = count($arr);
for ($i = $n - 2; $i >= 0; $i--) {
if ($arr[$i] < $arr[$i + 1]) {
for ($j = $n - 1; $j > $i; $j--) {
if ($arr[$j] > $arr[$i]) {
list($arr[$i], $arr[$j]) = [$arr[$j], $arr[$i]];
$left = array_slice($arr, 0, $i + 1);
$right = array_reverse(array_slice($arr, $i + 1));
$arr = array_merge($left, $right);
return true;
}
}
}
}
return false;
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1031. Maximum Sum of Two Non-Overlapping Subarrays
Сложность: medium

Если задан целочисленный массив nums и два целых числа firstLen и secondLen, верните максимальную сумму элементов в двух непересекающихся подмассивах с длинами firstLen и secondLen. Массив с длиной firstLen может находиться до или после массива с длиной secondLen, но они должны быть непересекающимися. Подмассив - это смежная часть массива.

Пример:
Input: nums = [0,6,5,2,2,5,1,9,4], firstLen = 1, secondLen = 2
Output: 20


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

1⃣Предварительные вычисления:
Вычислите сумму всех подмассивов длины firstLen и secondLen и сохраните их в списках.

2⃣Поиск максимальной суммы:
Переберите все возможные позиции для подмассива длины firstLen и для каждого такого подмассива найдите максимальную сумму для подмассива длины secondLen, который не пересекается с текущим подмассивом длины firstLen.

3⃣Сравнение двух случаев:
Рассмотрите оба случая: подмассив длины firstLen до подмассива длины secondLen и подмассив длины secondLen до подмассива длины firstLen. Найдите максимальную сумму для каждого случая.

😎 Решение:
class Solution {
function maxSumTwoNoOverlap($nums, $firstLen, $secondLen) {
return max($this->maxSumNonOverlap($nums, $firstLen, $secondLen), $this->maxSumNonOverlap(array_reverse($nums), $secondLen, $firstLen));
}

private function maxSumNonOverlap($nums, $firstLen, $secondLen) {
$n = count($nums);
$prefix = array_fill(0, $n + 1, 0);
for ($i = 0; $i < $n; $i++) {
$prefix[$i + 1] = $prefix[$i] + $nums[$i];
}

$maxFirst = array_fill(0, $n, 0);
for ($i = $firstLen - 1; $i < $n; $i++) {
$maxFirst[$i] = max(($i > 0 ? $maxFirst[$i - 1] : 0), $prefix[$i + 1] - $prefix[$i + 1 - $firstLen]);
}

$maxSecond = array_fill(0, $n, 0);
for ($i = $secondLen - 1; $i < $n; $i++) {
$maxSecond[$i] = max(($i > 0 ? $maxSecond[$i - 1] : 0), $prefix[$i + 1] - $prefix[$i + 1 - $secondLen]);
}

$maxSum = 0;
for ($i = $firstLen + $secondLen - 1; $i < $n; $i++) {
$maxSum = max($maxSum, $maxFirst[$i - $secondLen] + ($prefix[$i + 1] - $prefix[$i + 1 - $secondLen]));
}

return $maxSum;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1017. Convert to Base -2
Сложность: medium

Если задано целое число n, верните двоичную строку, представляющую его в базе -2. Обратите внимание, что возвращаемая строка не должна содержать ведущих нулей, за исключением случаев, когда строка равна "0".

Пример:
Input: n = 2
Output: "110"


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

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

2⃣Вычисление цифр:
В цикле, пока число не равно 0, вычисляйте остаток от деления числа на -2.
Если остаток отрицательный, корректируйте его, добавляя 2, и увеличивайте число на 1.
Добавляйте остаток в начало строки.

3⃣Возврат результата:
Верните строку, представляющую число в базе -2. Если строка пустая, верните "0".

😎 Решение:
class Solution {
function baseNeg2($n) {
if ($n == 0) return "0";
$res = "";
while ($n != 0) {
$remainder = $n % -2;
$n = intdiv($n, -2);
if ($remainder < 0) {
$remainder += 2;
$n += 1;
}
$res = $remainder . $res;
}
return $res;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM