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

Тесты t.iss.one/+pSDoLEZBQRZlNmFi
Вопросы собесов t.iss.one/+RJaDhjYaQDo2Njcy
Вакансии t.iss.one/+J-DKRUtjUgMxZGNi
Download Telegram
Задача: 1337. The K Weakest Rows in a Matrix
Сложность: easy

Вам дана бинарная матрица размером m x n mat, состоящая из 1 (представляющих солдат) и 0 (представляющих гражданских лиц). Солдаты расположены перед гражданскими лицами. То есть, все 1 будут расположены слева от всех 0 в каждой строке.

Строка i слабее строки j, если выполнено одно из следующих условий:

Количество солдат в строке i меньше, чем в строке j.
Обе строки имеют одинаковое количество солдат, но i < j.
Верните индексы k самых слабых строк в матрице, упорядоченных от самой слабой к самой сильной.

Пример:
Input: mat = 
[[1,1,0,0,0],
[1,1,1,1,0],
[1,0,0,0,0],
[1,1,0,0,0],
[1,1,1,1,1]],
k = 3
Output: [2,0,3]
Explanation:
The number of soldiers in each row is:
- Row 0: 2
- Row 1: 4
- Row 2: 1
- Row 3: 2
- Row 4: 5
The rows ordered from weakest to strongest are [2,0,3,1,4].


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

1⃣Вычислите силу каждой строки матрицы и поместите пары сила/индекс в массив. Для каждой строки подсчитайте количество единиц (солдат) до первой нуля (гражданского), чтобы определить силу строки.

2⃣Отсортируйте массив пар по возрастанию силы, а в случае равенства силы — по возрастанию индекса. Для этого потребуется реализовать компаратор, который сравнивает сначала силу, а затем индекс.

3⃣Извлеките первые k индексов из отсортированного массива и верните их. Эти индексы будут соответствовать k самым слабым строкам в порядке от самой слабой к самой сильной.

😎 Решение:
class Solution {
function kWeakestRows($mat, $k) {
$m = count($mat);
$n = count($mat[0]);

$pairs = [];
for ($i = 0; $i < $m; $i++) {
$strength = 0;
for ($j = 0; $j < $n; $j++) {
if ($mat[$i][$j] == 0) break;
$strength++;
}
$pairs[] = [$strength, $i];
}

usort($pairs, function($a, $b) {
if ($a[0] == $b[0]) return $a[1] - $b[1];
return $a[0] - $b[0];
});

$indexes = [];
for ($i = 0; $i < $k; $i++) {
$indexes[] = $pairs[$i][1];
}
return $indexes;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Я боялся, что провалю собеседование. Так появился easyoffer

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

Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.

Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.

📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)

В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..

Тогда и пришла идея

А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.

Так родился easyoffer.

Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.

Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.

В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни

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

Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.

Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.

Все, кто поддержат проект до релиза, получат:

🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
Доступ к закрытому бета-тесту

Поддержать 👉 https://planeta.ru/campaigns/easyoffer

Спасибо, что верите в этот проект 🙌
Задача: 1219. Path with Maximum Gold
Сложность: medium

В золотом руднике размером m x n каждая ячейка содержит целое число, представляющее количество золота в этой ячейке, или 0, если она пуста.

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

Пример:
Input: grid = [[0,6,0],[5,8,7],[0,9,0]]
Output: 24
Explanation:
[[0,6,0],
[5,8,7],
[0,9,0]]
Path to get the maximum gold, 9 -> 8 -> 7.


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

1⃣Инициализация и подготовка:
Инициализируйте константный массив DIRECTIONS для направления перемещений.
Определите количество строк и столбцов в сетке.
Инициализируйте переменную maxGold для хранения максимального количества собранного золота.

2⃣Функция DFS и обратный трек:
Реализуйте функцию dfsBacktrack для поиска пути с максимальным золотом с помощью DFS и обратного трека.
Обрабатывайте базовый случай, проверяя выход за пределы сетки или ячейки без золота.
Пометьте текущую ячейку как посещённую и сохраните её значение.
Исследуйте каждую из четырёх смежных ячеек и обновите максимальное количество золота, если найден лучший путь.
Сбросьте текущую ячейку до её исходного значения для дальнейших исследований.

3⃣Поиск максимального золота:
Используйте вложенные циклы для каждой ячейки в сетке, чтобы найти максимальное количество золота, начиная с этой ячейки, с помощью функции dfsBacktrack.
Обновите maxGold при нахождении лучшего пути.
Верните maxGold.

😎 Решение:
class Solution {
private $directions = [0, 1, 0, -1, 0];

function getMaximumGold($grid) {
$rows = count($grid);
$cols = count($grid[0]);
$maxGold = 0;

for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
$maxGold = max($maxGold, $this->dfsBacktrack($grid, $rows, $cols, $row, $col));
}
}
return $maxGold;
}

private function dfsBacktrack(&$grid, $rows, $cols, $row, $col) {
if ($row < 0 || $col < 0 || $row >= $rows || $col >= $cols || $grid[$row][$col] == 0) {
return 0;
}
$originalVal = $grid[$row][$col];
$grid[$row][$col] = 0;
$maxGold = 0;

for ($i = 0; $i < 4; $i++) {
$maxGold = max($maxGold, $this->dfsBacktrack($grid, $rows, $cols, $row + $this->directions[$i], $col + $this->directions[$i + 1]));
}

$grid[$row][$col] = $originalVal;
return $maxGold + $originalVal;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1218. Longest Arithmetic Subsequence of Given Difference
Сложность: medium

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

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

Пример:
Input: arr = [1,5,7,8,5,3,4,2,1], difference = -2
Output: 4
Explanation: The longest arithmetic subsequence is [7,5,3,1].


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

1⃣Инициализируйте пустой хеш-таблицу dp и установите answer = 1.

2⃣Итеративно обработайте массив arr. Для каждого элемента arr[i]:
Вычислите before_a, максимальную длину арифметической подпоследовательности, заканчивающейся на arr[i] - difference:
- если arr[i] - difference существует в dp, установите before_a = dp[arr[i] - difference].
- в противном случае, установите before_a = 0.
Установите dp[arr[i]] = before_a + 1, обновите answer как answer = max(answer, dp[arr[i]]).

3⃣Верните answer после завершения итерации.

😎 Решение:
class Solution {
function longestSubsequence($arr, $difference) {
$dp = [];
$answer = 1;

foreach ($arr as $a) {
$beforeA = isset($dp[$a - $difference]) ? $dp[$a - $difference] : 0;
$dp[$a] = $beforeA + 1;
$answer = max($answer, $dp[$a]);
}

return $answer;
}
}


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

Дан целочисленный массив arr, посчитайте, сколько элементов x в нем есть таких, что x + 1 также находится в arr. Если в arr есть дубликаты, считайте их отдельно.

Пример:
Input: arr = [1,2,3]
Output: 2
Explanation: 1 and 2 are counted cause 2 and 3 are in arr.


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

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

2⃣Итерируйте по каждому элементу массива и используйте вспомогательную функцию для проверки, содержится ли элемент x + 1 в массиве.

3⃣Увеличьте счетчик, если x + 1 найден, и верните значение счетчика.

😎 Решение:
class Solution {
function countElements($arr) {
$count = 0;
foreach ($arr as $x) {
if ($this->integerInArray($arr, $x + 1)) {
$count++;
}
}
return $count;
}

function integerInArray($arr, $target) {
foreach ($arr as $x) {
if ($x == $target) {
return true;
}
}
return false;
}
}


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

На кампусе, представленном в виде двумерной сетки, есть n рабочих и m велосипедов, где n <= m. Каждый рабочий и велосипед имеют координаты на этой сетке.

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

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

Манхэттенское расстояние между двумя точками p1 и p2 вычисляется как Manhattan(p1, p2) = |p1.x - p2.x| + |p1.y - p2.y|.

Пример:
Input: text = "thestoryofleetcodeandme", words = ["story","fleet","leetcode"]
Output: [[3,7],[9,13],[10,17]]


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

1⃣Для каждого рабочего, начиная с рабочего с индексом 0, пройдите по всем велосипедам и назначьте велосипед рабочему, если он доступен (visited[bikeIndex] = false). После назначения велосипеда отметьте его как недоступный (visited[bikeIndex] = true). Добавьте Манхэттенское расстояние от этого назначения к общей текущей сумме расстояний, представленной currDistanceSum, и выполните рекурсивный вызов для следующего рабочего.

2⃣Когда рекурсивный вызов завершится, сделайте велосипед снова доступным, установив visited[bikeIndex] в false. Если мы назначили велосипеды всем рабочим, сравните currDistanceSum с smallestDistanceSum и обновите smallestDistanceSum соответственно.

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

😎 Решение:
class Solution {
private $smallestDistanceSum = PHP_INT_MAX;
private $visited = array_fill(0, 10, false);

private function findDistance($worker, $bike) {
return abs($worker[0] - $bike[0]) + abs($worker[1] - $bike[1]);
}

private function minimumDistanceSum($workers, $workerIndex, $bikes, $currDistanceSum) {
if ($workerIndex >= count($workers)) {
$this->smallestDistanceSum = min($this->smallestDistanceSum, $currDistanceSum);
return;
}

if ($currDistanceSum >= $this->smallestDistanceSum) {
return;
}

foreach ($bikes as $bikeIndex => $bike) {
if (!$this->visited[$bikeIndex]) {
$this->visited[$bikeIndex] = true;
$this->minimumDistanceSum($workers, $workerIndex + 1, $bikes,
$currDistanceSum + $this->findDistance($workers[$workerIndex], $bike));
$this->visited[$bikeIndex] = false;
}
}
}

public function assignBikes($workers, $bikes) {
$this->minimumDistanceSum($workers, 0, $bikes, 0);
return $this->smallestDistanceSum;
}
}


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

Есть автомобиль с пустыми сиденьями емкостью capacity. Автомобиль движется только на восток (то есть он не может повернуть и ехать на запад).

Дан целочисленный параметр capacity и массив поездок trips, где trips[i] = [numPassengersi, fromi, toi] указывает, что на i-й поездке numPassengersi пассажиров должны быть забраны на позиции fromi и высажены на позиции toi. Позиции заданы как количество километров на восток от начальной точки автомобиля.

Верните true, если возможно забрать и высадить всех пассажиров для всех указанных поездок, или false в противном случае.

Пример:
Input: trips = [[2,1,5],[3,3,7]], capacity = 4
Output: false


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

1⃣Простая идея заключается в том, чтобы пройти от начала до конца и проверить, превышает ли фактическая вместимость capacity.

2⃣Чтобы узнать фактическую вместимость, нужно просто знать изменение количества пассажиров в каждый момент времени.

3⃣Мы можем сохранить изменения количества пассажиров в каждый момент времени, отсортировать их по меткам времени и, наконец, пройтись по ним, чтобы проверить фактическую вместимость.

😎 Решение:
class Solution {
function carPooling($trips, $capacity) {
$timestamp = [];
foreach ($trips as $trip) {
$timestamp[$trip[1]] = ($timestamp[$trip[1]] ?? 0) + $trip[0];
$timestamp[$trip[2]] = ($timestamp[$trip[2]] ?? 0) - $trip[0];
}
ksort($timestamp);
$usedCapacity = 0;
foreach ($timestamp as $change) {
$usedCapacity += $change;
if ($usedCapacity > $capacity) {
return false;
}
}
return true;
}
}


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

Дана бинарная сетка размером n x n. В каждом ходе можно поменять местами любые две строки или любые два столбца.

Верните минимальное количество ходов, чтобы преобразовать сетку в шахматную доску. Если задача невыполнима, верните -1.

Шахматная доска — это доска, на которой ни один 0 и ни одна 1 не соприкасаются друг с другом по вертикали и горизонтали.

Пример:
Input: board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]]
Output: 2
Explanation: One potential sequence of moves is shown.
The first move swaps the first and second column.
The second move swaps the second and third row.


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

1⃣Для каждого набора строк (и столбцов соответственно) убедитесь, что существует только 2 вида линий в правильных количествах, которые являются противоположностями друг друга.

2⃣Затем для каждой возможной идеальной трансформации этой линии найдите минимальное количество перестановок, чтобы преобразовать эту линию в её идеальную и добавьте это к ответу. Например, [0, 1, 1, 1, 0, 0] имеет два идеала [0, 1, 0, 1, 0, 1] или [1, 0, 1, 0, 1, 0]; но [0, 1, 1, 1, 0] имеет только один идеал [1, 0, 1, 0, 1].

3⃣В Java мы используем целые числа для представления строк как двоичных чисел. Мы проверяем количество различий с [1, 0, 1, 0, 1, 0, ...] с помощью побитового исключающего ИЛИ с 0b010101010101.....01 = 0x55555555. Чтобы убедиться, что мы не добавляем излишне большие элементы.

😎 Решение:
class Solution {
function movesToChessboard($board) {
$N = count($board);
$ans = 0;

foreach ([$this->getCount($board), $this->getCount($this->transpose($board))] as $count) {
$values = array_values($count);
sort($values);
if (count($values) !== 2 || $values[0] !== intdiv($N, 2) || $values[1] !== intdiv($N + 1, 2)) {
return -1;
}

$keys = array_keys($count);
$line1 = $keys[0];
$line2 = $keys[1];
if (!$this->allOpposite($line1, $line2)) {
return -1;
}

$starts = $N % 2 === 0 ? [0, 1] : [substr_count($line1, '1') * 2 > $N ? 1 : 0];

$minSwaps = PHP_INT_MAX;
foreach ($starts as $start) {
$swaps = 0;
for ($i = 0; $i < $N; $i++) {
if ((int)$line1[$i] !== ($i % 2 === $start ? 1 : 0)) {
$swaps++;
}
}
$minSwaps = min($minSwaps, intdiv($swaps, 2));
}
$ans += $minSwaps;
}

return $ans;
}

private function getCount($board) {
$count = [];
foreach ($board as $row) {
$key = implode('', $row);
if (!isset($count[$key])) {
$count[$key] = 0;
}
$count[$key]++;
}
return $count;
}

private function transpose($board) {
$N = count($board);
$transposed = array_fill(0, $N, array_fill(0, $N, 0));
for ($i = 0; $i < $N; $i++) {
for ($j = 0; $j < $N; $j++) {
$transposed[$j][$i] = $board[$i][$j];
}
}
return $transposed;
}

private function allOpposite($line1, $line2) {
for ($i = 0; $i < strlen($line1); $i++) {
if ((int)$line1[$i] ^ (int)$line2[$i] === 0) {
return false;
}
}
return true;
}
}


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

Дан массив целых чисел nums, половина целых чисел в нем нечетные, а другая половина - четные. Отсортируйте массив так, чтобы во всех случаях, когда nums[i] нечетный, i был нечетным, а во всех случаях, когда nums[i] четный, i был четным. Верните любой массив ответов, удовлетворяющий этому условию.

Пример:
Input: nums = [4,2,5,7]
Output: [4,5,2,7]


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

1⃣Инициализировать два указателя even_idx и odd_idx для отслеживания позиций четных и нечетных индексов соответственно.

2⃣Пройти по массиву nums и для каждого элемента:
Если элемент четный, поместить его на позицию even_idx и увеличить even_idx на 2.
Если элемент нечетный, поместить его на позицию odd_idx и увеличить odd_idx на 2.

3⃣Вернуть отсортированный массив.

😎 Решение:
function sortArrayByParityII($nums) {
$result = array_fill(0, count($nums), 0);
$evenIdx = 0;
$oddIdx = 1;

foreach ($nums as $num) {
if ($num % 2 == 0) {
$result[$evenIdx] = $num;
$evenIdx += 2;
} else {
$result[$oddIdx] = $num;
$oddIdx += 2;
}
}

return $result;
}


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

Есть n лампочек, которые изначально выключены. Сначала вы включаете все лампочки, затем выключаете каждую вторую лампочку.
На третьем раунде вы переключаете каждую третью лампочку (включаете, если она выключена, или выключаете, если она включена). На i-ом раунде вы переключаете каждую i-ую лампочку. На n-ом раунде вы переключаете только последнюю лампочку.
Верните количество лампочек, которые будут включены после n раундов.

Пример:
Input: n = 3
Output: 1
Explanation: At first, the three bulbs are [off, off, off].
After the first round, the three bulbs are [on, on, on].
After the second round, the three bulbs are [on, off, on].
After the third round, the three bulbs are [on, off, off].
So you should return 1 because there is only one bulb is on.
Explanation: The two words can be "abcw", "xtfn".


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

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

2⃣Определение состояния лампочки
Лампочка останется включенной только в том случае, если у нее нечетное количество делителей, что возможно только для квадратных чисел.

3⃣Подсчет включенных лампочек
Количество лампочек, которые будут включены после n раундов.

😎 Решение:
class Solution {
function bulbSwitch($n) {
return floor(sqrt($n));
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача №21. Merge Two Sorted Lists
Сложность: easy

Вам даны заголовки двух отсортированных связанных списков list1 и list2. Объедините два списка в один отсортированный список. Список должен быть составлен путем сращивания узлов первых двух списков. Верните заголовок объединенного связанного списка.

Пример:
Input: list1 = [1,2,4], list2 = [1,3,4]  
Output: [1,1,2,3,4,4]


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

1⃣Создать новый список для объединенного результата.

2⃣Использовать указатели для прохождения по обоим спискам и добавления наименьшего элемента.

3⃣Добавить оставшиеся элементы после окончания одного из списков.

😎 Решение:
class Solution { 

function mergeTwoLists($list1, $list2) {
$newList = new ListNode();
$current = $newList;

while($list1 || $list2) {
if ($list1 && !$list2) {
$current->next = new ListNode($list1->val);
$list1 = $list1->next;
} elseif (!$list1 && $list2) {
$current->next = new ListNode($list2->val);
$list2 = $list2->next;
} else {
if ($list1->val <= $list2->val) {
$current->next = new ListNode($list1->val);
$list1 = $list1->next;
} else {
$current->next = new ListNode($list2->val);
$list2 = $list2->next;
}
}
$current = $current->next;
}

return $newList->next;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1003. Check If Word Is Valid After Substitutions
Сложность: medium

Дана строка s, определите, является ли она допустимой. Строка s допустима, если, начиная с пустой строки t = "", вы можете преобразовать t в s, выполнив следующую операцию любое количество раз: вставить строку "abc" в любую позицию в t. Более формально, t становится tleft + "abc" + tright, где t == tleft + tright. Обратите внимание, что tleft и tright могут быть пустыми. Верните true, если s - допустимая строка, иначе верните false.

Пример:
Input: s = "aabcbc"
Output: true


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

1⃣Проверка допустимости длины строки:
Проверьте, что длина строки s кратна 3. Если нет, верните false.

2⃣Использование стека для проверки:
Инициализируйте пустой стек. Проходите по каждому символу строки s.
Если текущий символ является 'c', проверьте, что два предыдущих символа в стеке - это 'b' и 'a' соответственно. Если это так, удалите 'b' и 'a' из стека. Если нет, верните false.
Если текущий символ не 'c', добавьте его в стек.

3⃣Проверка остатка стека:
В конце, если стек пуст, верните true. Иначе верните false.

😎 Решение:
class Solution {
function isValid($s) {
if (strlen($s) % 3 != 0) return false;

$stack = [];
for ($i = 0; $i < strlen($s); $i++) {
$char = $s[$i];
if ($char == 'c') {
if (count($stack) < 2 || array_pop($stack) != 'b' || array_pop($stack) != 'a') {
return false;
}
} else {
$stack[] = $char;
}
}

return empty($stack);
}
}


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

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

Реализуйте класс FirstUnique:
- FirstUnique(int[] nums) Инициализирует объект числами в очереди.
- int showFirstUnique() возвращает значение первого уникального элемента в очереди и возвращает -1, если такого элемента нет.
- void add(int value) вставляет значение в очередь.

Пример:
Input: 
["FirstUnique","showFirstUnique","add","showFirstUnique","add","showFirstUnique","add","showFirstUnique"]
[[[2,3,5]],[],[5],[],[2],[],[3],[]]
Output:
[null,2,null,2,null,3,null,-1]
Explanation:
FirstUnique firstUnique = new FirstUnique([2,3,5]);
firstUnique.showFirstUnique(); // return 2
firstUnique.add(5); // the queue is now [2,3,5,5]
firstUnique.showFirstUnique(); // return 2
firstUnique.add(2); // the queue is now [2,3,5,5,2]
firstUnique.showFirstUnique(); // return 3
firstUnique.add(3); // the queue is now [2,3,5,5,2,3]
firstUnique.showFirstUnique(); // return -1


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

1⃣Инициализируйте объект FirstUnique с числами в очереди, добавляя их в структуру данных для отслеживания уникальности и порядка.

2⃣Метод showFirstUnique возвращает значение первого уникального элемента в очереди, если таковой существует, или -1, если уникальных элементов нет.

3⃣Метод add добавляет новое значение в очередь. Если значение уже было добавлено ранее, обновляет его статус уникальности и удаляет его из множества уникальных значений, если оно больше не уникально.

😎 Решение:
class FirstUnique {
private $queue;
private $isUnique;

function __construct($nums) {
$this->queue = new SplDoublyLinkedList();
$this->isUnique = [];
foreach ($nums as $num) {
$this->add($num);
}
}

function showFirstUnique() {
while (!$this->queue->isEmpty() && !$this->isUnique[$this->queue->bottom()]) {
$this->queue->shift();
}
if ($this->queue->isEmpty()) {
return -1;
}
return $this->queue->bottom();
}

function add($value) {
if (!isset($this->isUnique[$value])) {
$this->isUnique[$value] = true;
$this->queue->push($value);
} elseif ($this->isUnique[$value]) {
$this->isUnique[$value] = false;
}
}
}


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

Дано целочисленный массив nums. Соседние целые числа в nums будут выполнять деление с плавающей запятой.
Например, для nums = [2,3,4] мы будем вычислять выражение "2/3/4".
Однако, вы можете добавить любое количество скобок в любое место, чтобы изменить приоритет операций. Вы хотите добавить эти скобки так, чтобы значение выражения после вычисления было максимальным.
Верните соответствующее выражение, которое имеет максимальное значение в строковом формате.

Пример:
Input: nums = [1000,100,10,2]
Output: "1000/(100/10/2)"
Explanation: 1000/(100/10/2) = 1000/((100/10)/2) = 200
However, the bold parenthesis in "1000/((100/10)/2)" are redundant since they do not influence the operation priority.
So you should return "1000/(100/10/2)".
Other cases:
1000/(100/10)/2 = 50
1000/(100/(10/2)) = 50
1000/100/10/2 = 0.5
1000/100/(10/2) = 2


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

1⃣Разверните оба числа. Инициализируйте массив ans с (N+M) нулями. Для каждой цифры во втором числе: держите переменную переноса, изначально равную 0. Инициализируйте массив (currentResult), начинающийся с некоторых нулей в зависимости от места цифры во втором числе.

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

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

😎 Решение:
class Solution {
private function addStrings($num1, $num2) {
$ans = [];
$carry = 0;
$n1 = count($num1);
$n2 = count($num2);

for ($i = 0; $i < max($n1, $n2) || $carry; $i++) {
$digit1 = $i < $n1 ? $num1[$i] : 0;
$digit2 = $i < $n2 ? $num2[$i] : 0;
$sum = $digit1 + $digit2 + $carry;
$carry = intdiv($sum, 10);
$ans[] = $sum % 10;
}
return $ans;
}

private function multiplyOneDigit($firstNumber, $secondNumberDigit, $numZeros) {
$currentResult = array_fill(0, $numZeros, 0);
$carry = 0;

for ($i = 0; $i < strlen($firstNumber); $i++) {
$multiplication = (intval($secondNumberDigit) * intval($firstNumber[$i])) + $carry;
$carry = intdiv($multiplication, 10);
$currentResult[] = $multiplication % 10;
}
if ($carry != 0) {
$currentResult[] = $carry;
}
return $currentResult;
}

public function multiply($firstNumber, $secondNumber) {
if ($firstNumber === "0" || $secondNumber === "0") {
return "0";
}

$firstNumber = strrev($firstNumber);
$secondNumber = strrev($secondNumber);

$ans = array_fill(0, strlen($firstNumber) + strlen($secondNumber), 0);

for ($i = 0; $i < strlen($secondNumber); $i++) {
$ans = $this->addStrings($this->multiplyOneDigit($firstNumber, $secondNumber[$i], $i), $ans);
}

while (end($ans) === 0) {
array_pop($ans);
}

return implode('', array_reverse($ans));
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Осталось всего 14 дней до завершения краудфандинга

Сейчас самое подходящее время подключиться, если вы ждали или откладывали:

Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
Бета-доступ к EasyOffer 2.0 (конец мая)

👉 Поддержать: https://planeta.ru/campaigns/easyoffer
Задача: 433. Minimum Genetic Mutation
Сложность: medium

Генетическая строка может быть представлена строкой длиной 8 символов, содержащей символы 'A', 'C', 'G' и 'T'.
Предположим, нам нужно исследовать мутацию от генетической строки startGene до генетической строки endGene, где одна мутация определяется как изменение одного символа в генетической строке.
Например, "AACCGGTT" --> "AACCGGTA" является одной мутацией.
Также существует генетический банк bank, который содержит все допустимые генетические мутации. Генетическая строка должна быть в банке, чтобы считаться допустимой.
Даны две генетические строки startGene и endGene и генетический банк bank, верните минимальное количество мутаций, необходимых для мутации от startGene до endGene. Если такой мутации не существует, верните -1.
Обратите внимание, что начальная строка считается допустимой, поэтому она может не быть включена в банк.

Пример:
Input: startGene = "AACCGGTT", endGene = "AACCGGTA", bank = ["AACCGGTA"]
Output: 1


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

1⃣Инициализируйте очередь и множество seen. Очередь будет использоваться для выполнения BFS, а множество seen будет использоваться для предотвращения повторного посещения одного и того же узла. Изначально в очередь и множество должен быть помещен startGene.

2⃣Выполняйте BFS. На каждом узле, если node == endGene, верните количество шагов, пройденных до этого момента. В противном случае, итеративно заменяйте каждый символ в строке на один из "A", "C", "G", "T" для нахождения соседей. Для каждого соседа, если он еще не был посещен и находится в bank, добавьте его в очередь и в множество seen.

3⃣Если BFS завершился и endGene не был найден, задача невыполнима. Верните -1.

😎 Решение:
function minMutation($start, $end, $bank) {
$queue = [$start];
$seen = [$start => true];
$steps = 0;

while (count($queue) > 0) {
$nodesInQueue = count($queue);

for ($j = 0; $j < $nodesInQueue; $j++) {
$node = array_shift($queue);

if ($node === $end) {
return $steps;
}

foreach (str_split("ACGT") as $c) {
for ($i = 0; $i < strlen($node); $i++) {
$neighbor = substr($node, 0, $i) . $c . substr($node, $i + 1);
if (!isset($seen[$neighbor]) && in_array($neighbor, $bank)) {
$queue[] = $neighbor;
$seen[$neighbor] = true;
}
}
}
}

$steps++;
}

return -1;
}

echo minMutation("AACCGGTT", "AACCGGTA", ["AACCGGTA"]) . "\n"; // Output: 1
echo minMutation("AACCGGTT", "AAACGGTA", ["AACCGGTA", "AACCGCTA", "AAACGGTA"]) . "\n"; // Output: 2
echo minMutation("AAAAACCC", "AACCCCCC", ["AAAACCCC", "AAACCCCC", "AACCCCCC"]) . "\n"; // Output: 3


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

На лимонадной стойке каждый лимонад стоит $5. Покупатели стоят в очереди, чтобы купить лимонад, и заказывают по одному (в порядке, указанном в массиве bills). Каждый покупатель покупает только один лимонад и платит либо $5, $10, либо $20. Вы должны предоставить правильную сдачу каждому покупателю, чтобы чистая сделка была такой, что покупатель платит $5.

Обратите внимание, что изначально у вас нет никакой сдачи.

Дан целочисленный массив bills, где bills[i] — купюра, которой платит i-й покупатель. Верните true, если вы можете предоставить каждому покупателю правильную сдачу, или false в противном случае.

Пример:
Input: bills = [5,5,5,10,20]
Output: true
Explanation:
From the first 3 customers, we collect three $5 bills in order.
From the fourth customer, we collect a $10 bill and give back a $5.
From the fifth customer, we give a $10 bill and a $5 bill.
Since all customers got correct change, we output true.


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

1⃣Инициализируем переменные для хранения количества пятерок и десяток. Если покупатель платит $5, добавляем эту купюру в наш запас.

2⃣Если покупатель платит $10, проверяем наличие пятерки для сдачи. Если пятерки нет, возвращаем false. В противном случае, уменьшаем количество пятерок и увеличиваем количество десяток.

3⃣Если покупатель платит $20, сначала пытаемся дать сдачу десяткой и пятеркой. Если это невозможно, проверяем наличие трех пятерок. Если не можем дать сдачу, возвращаем false. После обработки всех покупателей, возвращаем true.

😎 Решение:
class Solution {
function lemonadeChange($bills) {
$five = 0;
$ten = 0;
foreach ($bills as $bill) {
if ($bill == 5) {
$five++;
} elseif ($bill == 10) {
if ($five == 0) return false;
$five--;
$ten++;
} else {
if ($five > 0 && $ten > 0) {
$five--;
$ten--;
} elseif ($five >= 3) {
$five -= 3;
} else {
return false;
}
}
}
return true;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1413. Minimum Value to Get Positive Step by Step Sum
Сложность: easy

Дан массив целых чисел nums, вы начинаете с начального положительного значения startValue.

На каждой итерации вы вычисляете поэтапную сумму startValue плюс элементы из nums (слева направо).

Верните минимальное положительное значение startValue, такое что поэтапная сумма никогда не будет меньше 1.

Пример:
Input: nums = [-3,2,-3,4,2]
Output: 5
Explanation: If you choose startValue = 4, in the third iteration your step by step sum is less than 1.
step by step sum
startValue = 4 | startValue = 5 | nums
(4 -3 ) = 1 | (5 -3 ) = 2 | -3
(1 +2 ) = 3 | (2 +2 ) = 4 | 2
(3 -3 ) = 0 | (4 -3 ) = 1 | -3
(0 +4 ) = 4 | (1 +4 ) = 5 | 4
(4 +2 ) = 6 | (5 +2 ) = 7 | 2


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

1⃣Инициализируйте переменные startValue со значением 1 и total со значением startValue.

2⃣Итеративно добавляйте каждый элемент массива nums к total и проверяйте, не опускается ли total ниже 1.

3⃣Если total падает ниже 1, увеличьте startValue на 1 и повторите шаги 2-3. Если total остается не менее 1, верните текущее значение startValue.

😎 Решение:
class Solution {
function minStartValue($nums) {
$startValue = 1;
while (true) {
$total = $startValue;
$isValid = true;
foreach ($nums as $num) {
$total += $num;
if ($total < 1) {
$isValid = false;
break;
}
}
if ($isValid) {
return $startValue;
}
$startValue++;
}
}
}


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