Задача: 909. Snakes and Ladders
Сложность: medium
Вам дана доска с целочисленной матрицей n x n, клетки которой помечены метками от 1 до n2 в стиле Бустрофедона, начиная с левого нижнего края доски (т.е. board[n - 1][0]) и чередуя направление в каждой строке. Вы начинаете на клетке 1 доски. В каждый ход, начиная с клетки curr, вы делаете следующее: выбираете клетку назначения next с меткой в диапазоне [curr + 1, min(curr + 6, n2)]. Этот выбор имитирует результат стандартного броска 6-гранного кубика: то есть всегда существует не более 6 мест назначения, независимо от размера доски. Если next имеет змейку или лестницу, вы должны двигаться к месту назначения этой змейки или лестницы. В противном случае вы переходите на следующий. Игра заканчивается, когда вы достигаете клетки n2. Клетка доски в строке r и столбце c имеет змейку или лестницу, если board[r][c] != -1. Местом назначения этой змейки или лестницы является доска[r][c]. В клетках 1 и n2 нет змейки или лестницы. Обратите внимание, что вы можете взять змейку или лестницу не более одного раза за ход. Если конечный пункт змейки или лестницы является началом другой змейки или лестницы, вы не ходите по последующей змейке или лестнице. Например, предположим, что доска имеет вид [[-1,4],[-1,3]], и на первом ходу ваш конечный квадрат - 2. Вы ходите по лестнице до квадрата 3, но не ходите по последующей лестнице до 4. Верните наименьшее количество ходов, необходимое для достижения квадрата n2. Если достичь квадрата невозможно, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Представить доску в виде одномерного массива, чтобы легко определить позицию следующего хода.
2⃣ Использовать BFS (поиск в ширину) для минимизации количества ходов до клетки n2.
В каждом ходе проверять клетки от curr + 1 до min(curr + 6, n2) и перемещаться по змейкам и лестницам, если они существуют.
3⃣ Если достижение клетки n2 невозможно, вернуть -1.
😎 Решение:
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана доска с целочисленной матрицей n x n, клетки которой помечены метками от 1 до n2 в стиле Бустрофедона, начиная с левого нижнего края доски (т.е. board[n - 1][0]) и чередуя направление в каждой строке. Вы начинаете на клетке 1 доски. В каждый ход, начиная с клетки curr, вы делаете следующее: выбираете клетку назначения next с меткой в диапазоне [curr + 1, min(curr + 6, n2)]. Этот выбор имитирует результат стандартного броска 6-гранного кубика: то есть всегда существует не более 6 мест назначения, независимо от размера доски. Если next имеет змейку или лестницу, вы должны двигаться к месту назначения этой змейки или лестницы. В противном случае вы переходите на следующий. Игра заканчивается, когда вы достигаете клетки n2. Клетка доски в строке r и столбце c имеет змейку или лестницу, если board[r][c] != -1. Местом назначения этой змейки или лестницы является доска[r][c]. В клетках 1 и n2 нет змейки или лестницы. Обратите внимание, что вы можете взять змейку или лестницу не более одного раза за ход. Если конечный пункт змейки или лестницы является началом другой змейки или лестницы, вы не ходите по последующей змейке или лестнице. Например, предположим, что доска имеет вид [[-1,4],[-1,3]], и на первом ходу ваш конечный квадрат - 2. Вы ходите по лестнице до квадрата 3, но не ходите по последующей лестнице до 4. Верните наименьшее количество ходов, необходимое для достижения квадрата n2. Если достичь квадрата невозможно, верните -1.
Пример:
Input: board = [[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,35,-1,-1,13,-1],[-1,-1,-1,-1,-1,-1],[-1,15,-1,-1,-1,-1]]
Output: 4
В каждом ходе проверять клетки от curr + 1 до min(curr + 6, n2) и перемещаться по змейкам и лестницам, если они существуют.
function snakesAndLadders($board) {
$n = count($board);
$getPos = function($x) use ($n) {
$quot = intdiv($x - 1, $n);
$rem = ($x - 1) % $n;
$row = $n - 1 - $quot;
$col = $row % 2 != $n % 2 ? $rem : $n - 1 - $rem;
return [$row, $col];
};
$visited = [];
$queue = [[1, 0]]; // [current position, steps]
while ($queue) {
list($pos, $steps) = array_shift($queue);
for ($i = 1; $i <= 6; $i++) {
$nextPos = $pos + $i;
if ($nextPos > $n * $n) continue;
list($r, $c) = $getPos($nextPos);
if ($board[$r][$c] != -1) {
$nextPos = $board[$r][$c];
}
if ($nextPos == $n * $n) {
return $steps + 1;
}
if (!in_array($nextPos, $visited)) {
$visited[] = $nextPos;
$queue[] = [$nextPos, $steps + 1];
}
}
}
return -1;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 917. Reverse Only Letters4
Сложность: easy
Задав строку s, переверните ее в соответствии со следующими правилами: все символы, не являющиеся английскими буквами, остаются в той же позиции. Все английские буквы (строчные или прописные) должны быть перевернуты. Верните s после перевертывания.
Пример:
👨💻 Алгоритм:
1⃣ Создать массив для хранения только английских букв из строки s.
2⃣ Перевернуть массив с английскими буквами.
Пройти по строке s и заменить каждую английскую букву на соответствующую из перевернутого массива.
3⃣ Вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Задав строку s, переверните ее в соответствии со следующими правилами: все символы, не являющиеся английскими буквами, остаются в той же позиции. Все английские буквы (строчные или прописные) должны быть перевернуты. Верните s после перевертывания.
Пример:
Input: s = "ab-cd"
Output: "dc-ba"
Пройти по строке s и заменить каждую английскую букву на соответствующую из перевернутого массива.
function reverseOnlyLetters($s) {
$letters = [];
for ($i = 0; $i < strlen($s); $i++) {
if (ctype_alpha($s[$i])) {
$letters[] = $s[$i];
}
}
$letters = array_reverse($letters);
$result = '';
$idx = 0;
for ($i = 0; $i < strlen($s); $i++) {
if (ctype_alpha($s[$i])) {
$result .= $letters[$idx++];
} else {
$result .= $s[$i];
}
}
return $result;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
⏳ Осталось 3 дня!
Финальный отсчёт пошёл — осталось всего 3 дня до окончания краудфандинга easyoffer 2.0
Сейчас можно получить максимум пользы за минимальные деньги. После окончания кампании цены вырастут и вознаграждения станут недоступны.
👉 Поддержи easyoffer 2.0 и получи:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
Поддержи проект сейчас, чтобы не забыть!
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Финальный отсчёт пошёл — осталось всего 3 дня до окончания краудфандинга easyoffer 2.0
Сейчас можно получить максимум пользы за минимальные деньги. После окончания кампании цены вырастут и вознаграждения станут недоступны.
👉 Поддержи easyoffer 2.0 и получи:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
Поддержи проект сейчас, чтобы не забыть!
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Задача: 337. House Robber III
Сложность: medium
Вор снова нашел себе новое место для краж. В этом районе есть только один вход, который называется корнем.
Кроме корня, каждый дом имеет только один родительский дом. После осмотра, умный вор понял, что все дома в этом месте образуют бинарное дерево. Полиция будет автоматически уведомлена, если два дома, напрямую связанные между собой, будут ограблены в одну ночь.
Дано корневое дерево бинарного дерева, верните максимальную сумму денег, которую вор может украсть, не уведомляя полицию.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и базовый случай:
Создайте вспомогательную функцию helper, которая принимает узел в качестве входных данных и возвращает массив из двух элементов, где первый элемент представляет максимальную сумму денег, которую можно украсть, если не грабить этот узел, а второй элемент - если грабить этот узел.
Базовый случай для вспомогательной функции - узел null, и в этом случае функция возвращает массив из двух нулей [0, 0].
2⃣ Рекурсивное исследование дерева:
В функции helper вызывайте её рекурсивно для левого и правого поддеревьев текущего узла.
Если грабить текущий узел, то нельзя грабить его потомков, поэтому сумма будет равна значению текущего узла плюс максимальные суммы для случаев, когда потомки не грабятся.
Если не грабить текущий узел, то можно свободно выбирать, грабить потомков или нет, поэтому сумма будет равна максимальной сумме из двух вариантов для каждого потомка.
3⃣ Возврат результата:
В основной функции rob вызовите helper для корня дерева и верните максимальное значение из двух элементов массива, возвращенного функцией helper.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вор снова нашел себе новое место для краж. В этом районе есть только один вход, который называется корнем.
Кроме корня, каждый дом имеет только один родительский дом. После осмотра, умный вор понял, что все дома в этом месте образуют бинарное дерево. Полиция будет автоматически уведомлена, если два дома, напрямую связанные между собой, будут ограблены в одну ночь.
Дано корневое дерево бинарного дерева, верните максимальную сумму денег, которую вор может украсть, не уведомляя полицию.
Пример:
Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
Создайте вспомогательную функцию helper, которая принимает узел в качестве входных данных и возвращает массив из двух элементов, где первый элемент представляет максимальную сумму денег, которую можно украсть, если не грабить этот узел, а второй элемент - если грабить этот узел.
Базовый случай для вспомогательной функции - узел null, и в этом случае функция возвращает массив из двух нулей [0, 0].
В функции helper вызывайте её рекурсивно для левого и правого поддеревьев текущего узла.
Если грабить текущий узел, то нельзя грабить его потомков, поэтому сумма будет равна значению текущего узла плюс максимальные суммы для случаев, когда потомки не грабятся.
Если не грабить текущий узел, то можно свободно выбирать, грабить потомков или нет, поэтому сумма будет равна максимальной сумме из двух вариантов для каждого потомка.
В основной функции 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];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 377. Combination Sum IV
Сложность: medium
Дан массив различных целых чисел nums и целое число target. Верните количество возможных комбинаций, которые в сумме дают target.
Тестовые случаи сгенерированы так, что ответ помещается в 32-битное целое число.
Пример:
👨💻 Алгоритм:
1⃣ В этом подходе мы начнем со стратегии сверху вниз, которая, пожалуй, более интуитивна. Как следует из названия, стратегия сверху вниз начинается с исходных данных, и затем мы рекурсивно уменьшаем входные данные до меньшего масштаба, пока не достигнем уровней, которые больше невозможно разбить.
2⃣ Из-за рекурсивной природы формулы мы можем напрямую перевести формулу в рекурсивную функцию.
3⃣ Здесь, соответственно, мы определяем рекурсивную функцию под названием combs(remain), которая возвращает количество комбинаций, где каждая комбинация в сумме дает значение remain.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив различных целых чисел nums и целое число target. Верните количество возможных комбинаций, которые в сумме дают target.
Тестовые случаи сгенерированы так, что ответ помещается в 32-битное целое число.
Пример:
Input: nums = [9], target = 3
Output: 0
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;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Завтра последний день!
Краудфандинг заканчивается уже завтра, и второй попытки не будет.
👉 Поддержи easyoffer 2.0 и получи:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Краудфандинг заканчивается уже завтра, и второй попытки не будет.
👉 Поддержи easyoffer 2.0 и получи:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Задача: 461. Hamming Distance
Сложность: easy
Расстояние Хэмминга между двумя целыми числами — это количество позиций, в которых соответствующие биты различны.
Даны два целых числа x и y, верните расстояние Хэмминга между ними.
Пример:
👨💻 Алгоритм:
1⃣ Во-первых, стоит упомянуть, что в большинстве (или, по крайней мере, во многих) языков программирования есть встроенные функции для подсчета битов, установленных в 1. Если вам нужно решить такую задачу в реальном проекте, то лучше использовать эти функции, чем изобретать велосипед.
2⃣ Однако, поскольку это задача на LeetCode, использование встроенных функций можно сравнить с "реализацией LinkedList с использованием LinkedList". Поэтому рассмотрим также несколько интересных ручных алгоритмов для подсчета битов.
3⃣ Пошаговый подсчет битов:
Выполните побитовое XOR между x и y.
Инициализируйте счетчик bitCount = 0.
Пока число не равно нулю:
Если текущий бит равен 1, увеличьте bitCount.
Сдвиньте число вправо на один бит.
Возвращайте bitCount.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Расстояние Хэмминга между двумя целыми числами — это количество позиций, в которых соответствующие биты различны.
Даны два целых числа x и y, верните расстояние Хэмминга между ними.
Пример:
Input: x = 3, y = 1
Output: 1
Выполните побитовое XOR между x и y.
Инициализируйте счетчик bitCount = 0.
Пока число не равно нулю:
Если текущий бит равен 1, увеличьте bitCount.
Сдвиньте число вправо на один бит.
Возвращайте bitCount.
class Solution {
public function hammingDistance($x, $y) {
return substr_count(decbin($x ^ $y), '1');
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
🚨 Последний шанс!
Сегодня — последний день краудфандинга.
Через несколько часов всё закроется, и больше невозможно будет поучаствовать.
Если ты хотел, но откладывал — СЕЙЧАС самое время. Займёт 2 минуты, но изменит твой подход к собеседованиям надолго.
Поддержи easyoffer 2.0 и получи:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
PRO подписка к easyoffer 2.0:
✅ Доступ к списку вопросов, которые задаются на собеседованиях + вероятность встречи этих вопросов + их фильтрация по грейдам, типам интервью, компаниям
✅ Доступ к лучшим ответам на вопросы
✅ Список самых частых задач, которые задаются на собеседовании + их фильтрация по грейдам и компаниям
✅ Доступ к лучшим ответам на задачи
✅ Список тестовых заданий компаний + лучшее решение
✅ Доступ к тренажеру "Проработка вопросов", который позволит очень быстро подготовиться к самым частым вопросам
✅ Доступ к тренажеру "Реальное собеседование", который позволит тренироваться проходить собеседование в конкретную компанию
До конца кампании — остались часы.
Поддержать: https://planeta.ru/campaigns/easyoffer
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Сегодня — последний день краудфандинга.
Через несколько часов всё закроется, и больше невозможно будет поучаствовать.
Если ты хотел, но откладывал — СЕЙЧАС самое время. Займёт 2 минуты, но изменит твой подход к собеседованиям надолго.
Поддержи easyoffer 2.0 и получи:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
PRO подписка к easyoffer 2.0:
✅ Доступ к списку вопросов, которые задаются на собеседованиях + вероятность встречи этих вопросов + их фильтрация по грейдам, типам интервью, компаниям
✅ Доступ к лучшим ответам на вопросы
✅ Список самых частых задач, которые задаются на собеседовании + их фильтрация по грейдам и компаниям
✅ Доступ к лучшим ответам на задачи
✅ Список тестовых заданий компаний + лучшее решение
✅ Доступ к тренажеру "Проработка вопросов", который позволит очень быстро подготовиться к самым частым вопросам
✅ Доступ к тренажеру "Реальное собеседование", который позволит тренироваться проходить собеседование в конкретную компанию
До конца кампании — остались часы.
Поддержать: https://planeta.ru/campaigns/easyoffer
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Задача: 848. Shifting Letters
Сложность: medium
Вам дана строка s из строчных букв английского алфавита и целочисленный массив shifts такой же длины.
Назовем shift() буквы следующей буквой в алфавите (с переходом так, что 'z' становится 'a').
Например, shift('a') = 'b', shift('t') = 'u', и shift('z') = 'a'.
Теперь для каждого shifts[i] = x мы хотим сдвинуть первые i + 1 букв строки s на x раз.
Верните итоговую строку после применения всех таких сдвигов к s.
Пример:
👨💻 Алгоритм:
1⃣ Вычислите общее количество сдвигов для всех символов строки, используя массив shifts.
2⃣ Пройдите по строке s и примените вычисленные сдвиги к каждому символу, начиная с первого и уменьшая количество сдвигов на текущем шаге.
3⃣ Постройте и верните итоговую строку после всех сдвигов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана строка s из строчных букв английского алфавита и целочисленный массив shifts такой же длины.
Назовем shift() буквы следующей буквой в алфавите (с переходом так, что 'z' становится 'a').
Например, shift('a') = 'b', shift('t') = 'u', и shift('z') = 'a'.
Теперь для каждого shifts[i] = x мы хотим сдвинуть первые i + 1 букв строки s на x раз.
Верните итоговую строку после применения всех таких сдвигов к s.
Пример:
Input: s = "abc", shifts = [3,5,9]
Output: "rpl"
Explanation: We start with "abc".
After shifting the first 1 letters of s by 3, we have "dbc".
After shifting the first 2 letters of s by 5, we have "igc".
After shifting the first 3 letters of s by 9, we have "rpl", the answer.
class Solution {
/**
* @param String $s
* @param Integer[] $shifts
* @return String
*/
function shiftingLetters($s, $shifts) {
$totalShifts = array_sum($shifts) % 26;
$sArray = str_split($s);
for ($i = 0; $i < count($sArray); $i++) {
$newCharValue = (ord($sArray[$i]) - ord('a') + $totalShifts) % 26;
$sArray[$i] = chr($newCharValue + ord('a'));
$totalShifts = ($totalShifts - $shifts[$i] + 26) % 26;
}
return implode('', $sArray);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
⏳ Такого больше не будет!
Всего пара часов и больше не будет возможности получить:
🚀 PRO подписку к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
Всего пара часов и больше не будет возможности получить:
🚀 PRO подписку к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу. ➕ Приглашение на закрытое бета-тестирование
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
Задача: 1482. Minimum Number of Days to Make m Bouquets
Сложность: medium
Вам дан массив целых чисел bloomDay, целое число m и целое число k.
Вам нужно сделать m букетов. Для создания букета необходимо использовать k соседних цветов из сада.
Сад состоит из n цветов, i-й цветок расцветет на bloomDay[i] и затем может быть использован ровно в одном букете.
Верните минимальное количество дней, которое нужно подождать, чтобы можно было сделать m букетов из сада. Если сделать m букетов невозможно, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация:
Инициализируйте start как 0 и end как максимальное значение в массиве bloomDay.
Введите вспомогательную функцию getNumOfBouquets для подсчета количества букетов, которые можно сделать на определенный день.
2⃣ Поиск минимального числа дней:
Выполняйте бинарный поиск, пока start меньше или равен end:
- рассчитайте mid как среднее значение между start и end.
- используйте getNumOfBouquets, чтобы определить, сколько букетов можно сделать на mid день.
- если количество букетов больше или равно m, сохраните mid как возможное решение и переместите end влево.
- иначе переместите start вправо.
3⃣ Возвращение результата:
Верните найденное минимальное количество дней или -1, если сделать m букетов невозможно.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан массив целых чисел bloomDay, целое число m и целое число k.
Вам нужно сделать m букетов. Для создания букета необходимо использовать k соседних цветов из сада.
Сад состоит из n цветов, i-й цветок расцветет на bloomDay[i] и затем может быть использован ровно в одном букете.
Верните минимальное количество дней, которое нужно подождать, чтобы можно было сделать m букетов из сада. Если сделать m букетов невозможно, верните -1.
Пример:
Input: bloomDay = [1,10,3,10,2], m = 3, k = 1
Output: 3
Explanation: Let us see what happened in the first three days. x means flower bloomed and _ means flower did not bloom in the garden.
We need 3 bouquets each should contain 1 flower.
After day 1: [x, _, _, _, _] // we can only make one bouquet.
After day 2: [x, _, _, _, x] // we can only make two bouquets.
After day 3: [x, _, x, _, x] // we can make 3 bouquets. The answer is 3.
Инициализируйте start как 0 и end как максимальное значение в массиве bloomDay.
Введите вспомогательную функцию getNumOfBouquets для подсчета количества букетов, которые можно сделать на определенный день.
Выполняйте бинарный поиск, пока start меньше или равен end:
- рассчитайте mid как среднее значение между start и end.
- используйте getNumOfBouquets, чтобы определить, сколько букетов можно сделать на mid день.
- если количество букетов больше или равно m, сохраните mid как возможное решение и переместите end влево.
- иначе переместите start вправо.
Верните найденное минимальное количество дней или -1, если сделать m букетов невозможно.
class Solution {
private function getNumOfBouquets($bloomDay, $mid, $k) {
$numOfBouquets = 0;
$count = 0;
foreach ($bloomDay as $day) {
if ($day <= $mid) {
$count++;
} else {
$count = 0;
}
if ($count == $k) {
$numOfBouquets++;
$count = 0;
}
}
return $numOfBouquets;
}
function minDays($bloomDay, $m, $k) {
if (count($bloomDay) < $m * $k) return -1;
$start = 0;
$end = max($bloomDay);
$minDays = -1;
while ($start <= $end) {
$mid = (int)(($start + $end) / 2);
if ($this->getNumOfBouquets($bloomDay, $mid, $k) >= $m) {
$minDays = $mid;
$end = $mid - 1;
} else {
$start = $mid + 1;
}
}
return $minDays;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Финальный отсчёт:
3 часа до конца краудфандинга easyoffer 2.0!
Это не просто скидка. Это шанс поддержать проект, который поможет и вам и тысячам айтишников готовиться к собеседованиям быстрее, эффективнее и увереннее.
За последние недели:
💥 Нас поддержали уже больше 1450 человек;
🔥 Вместе собрали больше 4,5 млн. рублей на запуск проекта;
Но сейчас важнее другое.
⏳ Через 3 часа всё закончится.
– Больше не будет подписки за 3 200 руб. на целый год!
– Не будет шанса первыми воспользоваться EasyOffer 2.0 на бета-тестировании
Если вы:
+ Планируете менять работу в этом или следующем году;
+ Хотите иметь под рукой 40,000+ вопросов собеседований с разборами, видео-ответами и тренажёрами;
+ Хотите зафиксировать лучшую цену на целый год… (потом будет в 12 раз дороже)
👉 Тогда просто переходите и поддержите нас сейчас:
https://planeta.ru/campaigns/easyoffer
📢 Три часа — и всё.
Не откладывайте на потом.
Спасибо всем, кто уже с нами! 💙
3 часа до конца краудфандинга easyoffer 2.0!
Это не просто скидка. Это шанс поддержать проект, который поможет и вам и тысячам айтишников готовиться к собеседованиям быстрее, эффективнее и увереннее.
За последние недели:
💥 Нас поддержали уже больше 1450 человек;
🔥 Вместе собрали больше 4,5 млн. рублей на запуск проекта;
Но сейчас важнее другое.
⏳ Через 3 часа всё закончится.
– Больше не будет подписки за 3 200 руб. на целый год!
– Не будет шанса первыми воспользоваться EasyOffer 2.0 на бета-тестировании
Если вы:
+ Планируете менять работу в этом или следующем году;
+ Хотите иметь под рукой 40,000+ вопросов собеседований с разборами, видео-ответами и тренажёрами;
+ Хотите зафиксировать лучшую цену на целый год… (потом будет в 12 раз дороже)
👉 Тогда просто переходите и поддержите нас сейчас:
https://planeta.ru/campaigns/easyoffer
📢 Три часа — и всё.
Не откладывайте на потом.
Спасибо всем, кто уже с нами! 💙
Forwarded from easyoffer
Через час мы закроем краудфандинг easyoffer 2.0
Это последний шанс вписаться в самые выгодные условия.
👉 https://planeta.ru/campaigns/easyoffer
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Идущий к IT
Я смотрю на эту цифру и до сих пор не верю.
Когда я запускал этот проект, мне реально было страшно. Страшно, что ничего не получится. Что я и мой проект никому не нужен. Страшно, что все увидят, как я публично обосрался.
Я ставил планку в 300т рублей. В самом позитивном сценарии 1млн. Но про 5 миллионов… даже мысли не было. Уже в первые часы стало понятно, что кампания идет не по плану. Сайт краудфандинга не выдержал нашей нагрузки и лег 😁
Особенно в последние три дня — просто какой-то разрыв! Я ощущал, как будто ловлю попутный ветер. В последний час не хватало 50к до 5 млн, и я уже думал сам их докинуть, чтобы красиво закрыть 😁
Но финальная сумма это не так важно. Самое главное это как мы её собрали. Это не инвестиции, не чьи-то деньги под условия и контроль, не кредит. Это вы поверили и поддержали меня напрямую. Вы дали мне возможность оставить за собой полный контроль над easyoffer.
Я чувствую огромную ответственность и нервничаю из-за высоких ожиданий. А вдруг что-то пойдёт не так? А вдруг на релизе кому-то что-то не понравится? Именно поэтому я рад, что могу честно выйти на новый этап и без давления от левых инвесторов.
В такие моменты вспоминаю, с чего всё начиналось. Как 2 года назад я писал свои первые посты на 500 человек о том, как учу программирование. Как записывал первое видео на YouTube про поиск работы. Как пилил первую версию easyoffer, вообще без понимания, что из этого выйдет.
И сейчас я думаю — может, эта история вдохновит кого-то из вас. Может, кто-то запустит свой айтишный проект, найдёт поддержку и соберёт бабки на развитие. Было бы круто
Спасибо за невероятную и колосальную поддержку ❤️
О такой аудитории как вы я не мог мечтать
Когда я запускал этот проект, мне реально было страшно. Страшно, что ничего не получится. Что я и мой проект никому не нужен. Страшно, что все увидят, как я публично обосрался.
Я ставил планку в 300т рублей. В самом позитивном сценарии 1млн. Но про 5 миллионов… даже мысли не было. Уже в первые часы стало понятно, что кампания идет не по плану. Сайт краудфандинга не выдержал нашей нагрузки и лег 😁
Особенно в последние три дня — просто какой-то разрыв! Я ощущал, как будто ловлю попутный ветер. В последний час не хватало 50к до 5 млн, и я уже думал сам их докинуть, чтобы красиво закрыть 😁
Но финальная сумма это не так важно. Самое главное это как мы её собрали. Это не инвестиции, не чьи-то деньги под условия и контроль, не кредит. Это вы поверили и поддержали меня напрямую. Вы дали мне возможность оставить за собой полный контроль над easyoffer.
Я чувствую огромную ответственность и нервничаю из-за высоких ожиданий. А вдруг что-то пойдёт не так? А вдруг на релизе кому-то что-то не понравится? Именно поэтому я рад, что могу честно выйти на новый этап и без давления от левых инвесторов.
В такие моменты вспоминаю, с чего всё начиналось. Как 2 года назад я писал свои первые посты на 500 человек о том, как учу программирование. Как записывал первое видео на YouTube про поиск работы. Как пилил первую версию easyoffer, вообще без понимания, что из этого выйдет.
И сейчас я думаю — может, эта история вдохновит кого-то из вас. Может, кто-то запустит свой айтишный проект, найдёт поддержку и соберёт бабки на развитие. Было бы круто
Спасибо за невероятную и колосальную поддержку ❤️
О такой аудитории как вы я не мог мечтать
Задача: 629. K Inverse Pairs Array
Сложность: hard
Для целочисленного массива nums инверсная пара - это пара целых чисел [i, j], где 0 <= i < j < nums.length и nums[i] > nums[j]. Учитывая два целых числа n и k, верните количество различных массивов, состоящих из чисел от 1 до n, в которых существует ровно k инверсных пар. Поскольку ответ может быть огромным, верните его по модулю 109 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Создайте двумерный массив dp размером [n+1][k+1] и установите начальное значение dp[0][0] = 1. Остальные значения установите в 0.
2⃣ Заполнение DP-таблицы
Используйте два вложенных цикла для заполнения таблицы DP. Внешний цикл перебирает длину массива i от 1 до n, а внутренний цикл перебирает количество инверсий j от 0 до k. Если j == 0, то dp[i][j] = 1. В противном случае обновляйте dp[i][j] с учетом всех возможных позиций вставки нового элемента в массив длины i-1.
3⃣ Возвращение результата
Результатом будет значение dp[n][k].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Для целочисленного массива nums инверсная пара - это пара целых чисел [i, j], где 0 <= i < j < nums.length и nums[i] > nums[j]. Учитывая два целых числа n и k, верните количество различных массивов, состоящих из чисел от 1 до n, в которых существует ровно k инверсных пар. Поскольку ответ может быть огромным, верните его по модулю 109 + 7.
Пример:
Input: n = 3, k = 0
Output: 1
Создайте двумерный массив dp размером [n+1][k+1] и установите начальное значение dp[0][0] = 1. Остальные значения установите в 0.
Используйте два вложенных цикла для заполнения таблицы DP. Внешний цикл перебирает длину массива i от 1 до n, а внутренний цикл перебирает количество инверсий j от 0 до k. Если j == 0, то dp[i][j] = 1. В противном случае обновляйте dp[i][j] с учетом всех возможных позиций вставки нового элемента в массив длины i-1.
Результатом будет значение dp[n][k].
function kInversePairs($n, $k) {
$MOD = 1000000007;
$dp = array_fill(0, $n + 1, array_fill(0, $k + 1, 0));
$dp[0][0] = 1;
for ($i = 1; $i <= $n; $i++) {
$dp[$i][0] = 1;
for ($j = 1; $j <= $k; $j++) {
$dp[$i][$j] = ($dp[$i][$j - 1] + $dp[$i - 1][$j]) % $MOD;
if ($j >= $i) {
$dp[$i][$j] = ($dp[$i][$j] - $dp[$i - 1][$j - $i] + $MOD) % $MOD;
}
}
}
return $dp[$n][$k];
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 925. Long Pressed Name
Сложность: easy
Ваш друг набирает на клавиатуре свое имя. Иногда, при наборе символа c, клавиша может быть долго нажата, и символ будет набран 1 или более раз. Вы исследуете набранные символы клавиатуры. Верните True, если возможно, что это было имя вашего друга, при этом некоторые символы (возможно, ни один) не были долго нажаты.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать два указателя i и j для строки имени и набранной строки соответственно.
2⃣ Пройти по набранной строке:
Если символы имени и набранной строки совпадают, сдвинуть оба указателя.
Если символы не совпадают, проверить, является ли текущий символ набранной строки повторением предыдущего символа. Если да, сдвинуть указатель набранной строки.
Если символ не совпадает и не является повторением предыдущего символа, вернуть False.
После завершения цикла проверить, что все символы имени были обработаны.
3⃣ Вернуть True, если все символы имени были обработаны, иначе False.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Ваш друг набирает на клавиатуре свое имя. Иногда, при наборе символа c, клавиша может быть долго нажата, и символ будет набран 1 или более раз. Вы исследуете набранные символы клавиатуры. Верните True, если возможно, что это было имя вашего друга, при этом некоторые символы (возможно, ни один) не были долго нажаты.
Пример:
Input: name = "alex", typed = "aaleex"
Output: true
Если символы имени и набранной строки совпадают, сдвинуть оба указателя.
Если символы не совпадают, проверить, является ли текущий символ набранной строки повторением предыдущего символа. Если да, сдвинуть указатель набранной строки.
Если символ не совпадает и не является повторением предыдущего символа, вернуть False.
После завершения цикла проверить, что все символы имени были обработаны.
function isLongPressedName($name, $typed) {
$i = 0;
$j = 0;
while ($j < strlen($typed)) {
if ($i < strlen($name) && $name[$i] == $typed[$j]) {
$i++;
} elseif ($j == 0 || $typed[$j] != $typed[$j - 1]) {
return false;
}
$j++;
}
return $i == strlen($name);
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 489. Robot Room Cleaner
Сложность: hard
Вы управляете роботом в комнате, представленной бинарной сеткой m x n, где 0 — стена, а 1 — пустая ячейка.
Робот начинает в неизвестном месте, гарантированно пустом. У вас нет доступа к сетке, но вы можете перемещать робота через предоставленный API Robot.
Роботу нужно очистить всю комнату (т.е. все пустые ячейки). Он может двигаться вперед, поворачивать налево или направо на 90 градусов.
Если робот наталкивается на стену, его датчик препятствия обнаруживает это, и он остается на текущей ячейке.
Разработайте алгоритм для очистки всей комнаты, используя следующие API:
Пример:
👨💻 Алгоритм:
1⃣ Пометьте текущую ячейку как посещенную и очистите её.
2⃣ Исследуйте четыре направления (вверх, вправо, вниз, влево) последовательно, двигаясь и очищая новые ячейки, если возможно.
3⃣ Если движение невозможно (стена или посещенная ячейка), поверните направо и попробуйте снова, возвращаясь назад, если необходимо.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вы управляете роботом в комнате, представленной бинарной сеткой m x n, где 0 — стена, а 1 — пустая ячейка.
Робот начинает в неизвестном месте, гарантированно пустом. У вас нет доступа к сетке, но вы можете перемещать робота через предоставленный API Robot.
Роботу нужно очистить всю комнату (т.е. все пустые ячейки). Он может двигаться вперед, поворачивать налево или направо на 90 градусов.
Если робот наталкивается на стену, его датчик препятствия обнаруживает это, и он остается на текущей ячейке.
Разработайте алгоритм для очистки всей комнаты, используя следующие API:
interface Robot {
// возвращает true, если следующая ячейка открыта и робот перемещается в эту ячейку.
// возвращает false, если следующая ячейка является препятствием и робот остается на текущей ячейке.
boolean move();
// Робот останется на той же ячейке после вызова turnLeft/turnRight.
// Каждый поворот составляет 90 градусов.
void turnLeft();
void turnRight();
// Очистить текущую ячейку.
void clean();
}Пример:
Input: room = [[1,1,1,1,1,0,1,1],[1,1,1,1,1,0,1,1],[1,0,1,1,1,1,1,1],[0,0,0,1,0,0,0,0],[1,1,1,1,1,1,1,1]], row = 1, col = 3
Output: Robot cleaned all rooms.
Explanation: All grids in the room are marked by either 0 or 1.
0 means the cell is blocked, while 1 means the cell is accessible.
The robot initially starts at the position of row=1, col=3.
From the top left corner, its position is one row below and three columns right.
class Solution {
private $robot;
private $visited;
private $directions;
public function __construct() {
$this->visited = [];
$this->directions = [[-1, 0], [0, 1], [1, 0], [0, -1]];
}
private function goBack() {
$this->robot->turnRight();
$this->robot->turnRight();
$this->robot->move();
$this->robot->turnRight();
$this->robot->turnRight();
}
private function backtrack($row, $col, $d) {
$this->visited["$row,$col"] = true;
$this->robot->clean();
for ($i = 0; $i < 4; $i++) {
$newD = ($d + $i) % 4;
$newRow = $row + $this->directions[$newD][0];
$newCol = $col + $this->directions[$newD][1];
if (!isset($this->visited["$newRow,$newCol"]) && $this->robot->move()) {
$this->backtrack($newRow, $newCol, $newD);
$this->goBack();
}
$this->robot->turnRight();
}
}
public function cleanRoom($robot) {
$this->robot = $robot;
$this->backtrack(0, 0, 0);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 668. Kth Smallest Number in Multiplication Table
Сложность: hard
Почти каждый использовал таблицу умножения. Таблица умножения размером m x n - это целочисленная матрица mat, где mat[i][j] == i * j (индексация начинается с 1).
Даны три целых числа m, n и k. Верните k-й наименьший элемент в таблице умножения размером m x n.
Пример:
👨💻 Алгоритм:
1⃣ Установка границ поиска:
Установите нижнюю границу left равной 1 и верхнюю границу right равной m * n.
2⃣ Бинарный поиск:
Используйте бинарный поиск, чтобы найти k-й наименьший элемент.
Для каждого среднего значения mid, посчитайте количество элементов в таблице умножения, которые меньше или равны mid.
3⃣ Проверка количества элементов:
Если количество элементов меньше k, увеличьте нижнюю границу (left).
Если количество элементов больше или равно k, уменьшите верхнюю границу (right).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Почти каждый использовал таблицу умножения. Таблица умножения размером m x n - это целочисленная матрица mat, где mat[i][j] == i * j (индексация начинается с 1).
Даны три целых числа m, n и k. Верните k-й наименьший элемент в таблице умножения размером m x n.
Пример:
Input: m = 3, n = 3, k = 5
Output: 3
Explanation: The 5th smallest number is 3.
Установите нижнюю границу left равной 1 и верхнюю границу right равной m * n.
Используйте бинарный поиск, чтобы найти k-й наименьший элемент.
Для каждого среднего значения mid, посчитайте количество элементов в таблице умножения, которые меньше или равны mid.
Если количество элементов меньше k, увеличьте нижнюю границу (left).
Если количество элементов больше или равно k, уменьшите верхнюю границу (right).
class Solution {
function findKthNumber($m, $n, $k) {
$left = 1;
$right = $m * $n;
while ($left < $right) {
$mid = intdiv($left + $right, 2);
if ($this->countLessEqual($m, $n, $mid) < $k) {
$left = $mid + 1;
} else {
$right = $mid;
}
}
return $left;
}
private function countLessEqual($m, $n, $x) {
$count = 0;
for ($i = 1; $i <= $m; $i++) {
$count += min(intdiv($x, $i), $n);
}
return $count;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 116. Populating Next Right Pointers in Each Node
Сложность: medium
Вам дано идеальное бинарное дерево, где все листья находятся на одном уровне, и у каждого родителя есть два детей. Бинарное дерево имеет следующее определение:
Заполните каждый указатель
Изначально все указатели
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте очередь Q, которую мы будем использовать во время обхода. Существует несколько способов реализации обхода в ширину, особенно когда речь идет о определении уровня конкретного узла. Можно добавлять в очередь пару (узел, уровень), и каждый раз, когда добавляются дети узла, мы добавляем (node.left, parent_level + 1) и (node.right, parent_level + 1). Этот подход не будет очень эффективен для нашего алгоритма, так как нам нужны все узлы на одном уровне, и для этого потребуется еще одна структура данных.
2⃣ Более эффективный с точки зрения памяти способ разделения узлов одного уровня заключается в использовании некоторой разграничительной метки между уровнями. Обычно мы вставляем в очередь элемент NULL, который отмечает конец предыдущего уровня и начало следующего. Это отличный подход, но он все равно потребует некоторого количества памяти, пропорционально количеству уровней в дереве.
3⃣ Подход, который мы будем использовать здесь, будет иметь структуру вложенных циклов, чтобы обойти необходимость указателя NULL. По сути, на каждом шаге мы записываем размер очереди, который всегда соответствует всем узлам на определенном уровне. Как только мы узнаем этот размер, мы обрабатываем только это количество элементов и не более. К моменту, когда мы закончим обработку заданного количества элементов, в очереди будут все узлы следующего уровня. Вот псевдокод для этого:
Мы начинаем с добавления корня дерева в очередь. Поскольку на уровне 0 есть только один узел, нам не нужно устанавливать какие-либо соединения, и мы можем перейти к циклу while.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дано идеальное бинарное дерево, где все листья находятся на одном уровне, и у каждого родителя есть два детей. Бинарное дерево имеет следующее определение:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}Заполните каждый указатель
next так, чтобы он указывал на следующий правый узел. Если следующего правого узла нет, указатель next должен быть установлен в NULL.Изначально все указатели
next установлены в NULL.Пример:
Input: root = [1,2,3,4,5,6,7]
Output: [1,#,2,3,#,4,5,6,7,#]
Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.
while (!Q.empty())
{
size = Q.size()
for i in range 0..size
{
node = Q.pop()
Q.push(node.left)
Q.push(node.right)
}
}
Мы начинаем с добавления корня дерева в очередь. Поскольку на уровне 0 есть только один узел, нам не нужно устанавливать какие-либо соединения, и мы можем перейти к циклу while.
class Node {
public $val;
public $left = null;
public $right = null;
public $next = null;
public function __construct($val) {
$this->val = $val;
}
}
class Solution {
public function connect($root) {
if ($root === null) {
return $root;
}
$queue = new SplQueue();
$queue->enqueue($root);
while (!$queue->isEmpty()) {
$size = $queue->count();
for ($i = 0; $i < $size; $i++) {
$node = $queue->dequeue();
if ($i < $size - 1) {
$node->next = $queue->top();
}
if ($node->left !== null) {
$queue->enqueue($node->left);
}
if ($node->right !== null) {
$queue->enqueue($node->right);
}
}
}
return $root;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1002. Find Common Characters
Сложность: easy
Если задан массив строк words, верните массив всех символов, которые встречаются во всех строках внутри слов (включая дубликаты). Вы можете вернуть ответ в любом порядке.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация частотного массива:
Создайте массив для хранения минимальной частоты каждого символа, который будет встречаться во всех словах.
2⃣ Обработка каждого слова:
Для каждого слова создайте временный массив для хранения частоты каждого символа в этом слове.
Обновите основной частотный массив, сравнивая его с временным массивом и сохраняя минимальные частоты каждого символа.
3⃣ Формирование результата:
Создайте результирующий массив, добавляя каждый символ столько раз, сколько его минимальная частота.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Если задан массив строк words, верните массив всех символов, которые встречаются во всех строках внутри слов (включая дубликаты). Вы можете вернуть ответ в любом порядке.
Пример:
Input: words = ["bella","label","roller"]
Output: ["e","l","l"]
Создайте массив для хранения минимальной частоты каждого символа, который будет встречаться во всех словах.
Для каждого слова создайте временный массив для хранения частоты каждого символа в этом слове.
Обновите основной частотный массив, сравнивая его с временным массивом и сохраняя минимальные частоты каждого символа.
Создайте результирующий массив, добавляя каждый символ столько раз, сколько его минимальная частота.
class Solution {
function commonChars($words) {
$minFreq = array_fill(0, 26, PHP_INT_MAX);
foreach ($words as $word) {
$freq = array_fill(0, 26, 0);
foreach (str_split($word) as $char) {
$freq[ord($char) - ord('a')]++;
}
for ($i = 0; $i < 26; $i++) {
$minFreq[$i] = min($minFreq[$i], $freq[$i]);
}
}
$result = [];
for ($i = 0; $i < 26; $i++) {
for ($j = 0; $j < $minFreq[$i]; $j++) {
$result[] = chr($i + ord('a'));
}
}
return $result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM