Задача: 928. Minimize Malware Spread II
Сложность: hard
Вам дана сеть из n узлов, представленная в виде графа с матрицей смежности n x n, где i-й узел непосредственно связан с j-м узлом, если graph[i][j] == 1. Некоторые узлы изначально заражены вредоносным ПО. Если два узла соединены напрямую и хотя бы один из них заражен вредоносным ПО, то оба узла будут заражены вредоносным ПО. Такое распространение вредоносного ПО будет продолжаться до тех пор, пока больше не останется ни одного узла, зараженного таким образом. Предположим, что M(initial) - это конечное число узлов, зараженных вредоносным ПО, во всей сети после прекращения распространения вредоносного ПО. Мы удалим ровно один узел из initial, полностью удалив его и все связи от этого узла к любому другому узлу. Верните узел, который, если его удалить, минимизирует M(initial). Если для минимизации M(initial) можно удалить несколько узлов, верните такой узел с наименьшим индексом.
Пример:
👨💻 Алгоритм:
1⃣ Определить компоненты связности в графе.
Для каждой компоненты связности определить количество зараженных узлов и общее количество узлов.
2⃣ Для каждого узла в initial удалить его и пересчитать количество зараженных узлов.
3⃣ Найти узел, удаление которого минимизирует количество зараженных узлов. Если несколько узлов минимизируют количество зараженных узлов одинаково, выбрать узел с наименьшим индексом.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дана сеть из n узлов, представленная в виде графа с матрицей смежности n x n, где i-й узел непосредственно связан с j-м узлом, если graph[i][j] == 1. Некоторые узлы изначально заражены вредоносным ПО. Если два узла соединены напрямую и хотя бы один из них заражен вредоносным ПО, то оба узла будут заражены вредоносным ПО. Такое распространение вредоносного ПО будет продолжаться до тех пор, пока больше не останется ни одного узла, зараженного таким образом. Предположим, что M(initial) - это конечное число узлов, зараженных вредоносным ПО, во всей сети после прекращения распространения вредоносного ПО. Мы удалим ровно один узел из initial, полностью удалив его и все связи от этого узла к любому другому узлу. Верните узел, который, если его удалить, минимизирует M(initial). Если для минимизации M(initial) можно удалить несколько узлов, верните такой узел с наименьшим индексом.
Пример:
Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
Output: 0
Для каждой компоненты связности определить количество зараженных узлов и общее количество узлов.
function minMalwareSpread($graph, $initial) {
$n = count($graph);
$components = [];
$visited = [];
function dfs($graph, $node, &$component, &$visited) {
$stack = [$node];
while (!empty($stack)) {
$u = array_pop($stack);
if (!isset($visited[$u])) {
$visited[$u] = true;
$component[] = $u;
foreach ($graph[$u] as $v => $connected) {
if ($connected == 1 && !isset($visited[$v])) {
$stack[] = $v;
}
}
}
}
}
for ($i = 0; $i < $n; $i++) {
if (!isset($visited[$i])) {
$component = [];
dfs($graph, $i, $component, $visited);
$components[] = $component;
}
}
$infectedInComponent = array_fill(0, count($components), 0);
$nodeToComponent = array_fill(0, $n, -1);
foreach ($components as $idx => $component) {
foreach ($component as $node) {
$nodeToComponent[$node] = $idx;
if (in_array($node, $initial)) {
$infectedInComponent[$idx]++;
}
}
}
$minInfected = PHP_INT_MAX;
$resultNode = min($initial);
foreach ($initial as $node) {
$componentIdx = $nodeToComponent[$node];
if ($infectedInComponent[$componentIdx] == 1) {
$componentSize = count($components[$componentIdx]);
if ($componentSize < $minInfected || ($componentSize == $minInfected && $node < $resultNode)) {
$minInfected = $componentSize;
$resultNode = $node;
}
}
}
return $resultNode;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 720. Longest Word in Dictionary
Сложность: medium
Если задан массив строк words, представляющих английский словарь, верните самое длинное слово из words, которое может быть построено по одному символу из других слов из words. Если существует более одного возможного ответа, верните самое длинное слово с наименьшим лексикографическим порядком. Если ответа нет, верните пустую строку. Обратите внимание, что слово должно строиться слева направо, причем каждый дополнительный символ добавляется в конец предыдущего слова.
Пример:
👨💻 Алгоритм:
1⃣ Отсортируйте массив слов по длине и лексикографическому порядку.
2⃣ Используйте множество для отслеживания слов, которые можно построить.
3⃣ Пройдите по каждому слову в отсортированном массиве и добавьте его в множество, если все его префиксы уже существуют в множестве.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан массив строк words, представляющих английский словарь, верните самое длинное слово из words, которое может быть построено по одному символу из других слов из words. Если существует более одного возможного ответа, верните самое длинное слово с наименьшим лексикографическим порядком. Если ответа нет, верните пустую строку. Обратите внимание, что слово должно строиться слева направо, причем каждый дополнительный символ добавляется в конец предыдущего слова.
Пример:
Input: words = ["w","wo","wor","worl","world"]
Output: "world"
function longestWord($words) {
sort($words);
$validWords = ["" => true];
$longest = "";
foreach ($words as $word) {
if (isset($validWords[substr($word, 0, -1)])) {
$validWords[$word] = true;
if (strlen($word) > strlen($longest)) {
$longest = $word;
}
}
}
return $longest;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 743. Network Delay Time
Сложность: medium
Дана сеть из узлов, помеченных от 1 до n. Также дано times - список времен прохождения сигнала в виде направленных ребер times[i] = (ui, vi, wi), где ui - исходный узел, vi - целевой узел, а wi - время прохождения сигнала от источника до цели. Мы пошлем сигнал из заданного узла k. Верните минимальное время, которое потребуется всем узлам, чтобы получить сигнал. Если все узлы не могут получить сигнал, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Представьте граф в виде списка смежности.
2⃣ Используйте алгоритм Дейкстры для нахождения кратчайших путей от узла k до всех других узлов.
3⃣ Найдите максимальное значение среди кратчайших путей к узлам. Если какой-либо узел недостижим, верните -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана сеть из узлов, помеченных от 1 до n. Также дано times - список времен прохождения сигнала в виде направленных ребер times[i] = (ui, vi, wi), где ui - исходный узел, vi - целевой узел, а wi - время прохождения сигнала от источника до цели. Мы пошлем сигнал из заданного узла k. Верните минимальное время, которое потребуется всем узлам, чтобы получить сигнал. Если все узлы не могут получить сигнал, верните -1.
Пример:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2
function networkDelayTime($times, $n, $k) {
$graph = [];
for ($i = 1; $i <= $n; $i++) {
$graph[$i] = [];
}
foreach ($times as $time) {
$graph[$time[0]][] = [$time[1], $time[2]];
}
$minHeap = new SplPriorityQueue();
$minHeap->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$minHeap->insert([$k, 0], 0);
$minTime = array_fill(1, $n, INF);
$minTime[$k] = 0;
while (!$minHeap->isEmpty()) {
$data = $minHeap->extract();
$time = $data['priority'];
$node = $data['data'][0];
foreach ($graph[$node] as $neighbor) {
$newTime = $time + $neighbor[1];
if ($newTime < $minTime[$neighbor[0]]) {
$minTime[$neighbor[0]] = $newTime;
$minHeap->insert([$neighbor[0], $newTime], -$newTime);
}
}
}
$maxTime = max($minTime);
return $maxTime == INF ? -1 : $maxTime;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 659. Split Array into Consecutive Subsequences
Сложность: medium
Вам дан отсортированный в неубывающем порядке массив целых чисел nums.
Определите, можно ли разделить nums на одну или несколько подпоследовательностей так, чтобы выполнялись оба следующих условия:
Каждая подпоследовательность является последовательностью последовательных возрастающих чисел (то есть каждое целое число на 1 больше предыдущего).
Все подпоследовательности имеют длину 3 или более.
Верните true, если можно разделить nums согласно вышеуказанным условиям, или false в противном случае.
Подпоследовательность массива — это новый массив, который формируется из исходного массива путем удаления некоторых (может быть, ни одного) элементов без нарушения относительных позиций оставшихся элементов. (например, [1,3,5] является подпоследовательностью [1,2,3,4,5], тогда как [1,3,2] не является).
Пример:
👨💻 Алгоритм:
1⃣ Подсчет частоты элементов:
Создайте хеш-таблицу для подсчета количества вхождений каждого элемента в массиве nums.
2⃣ Создание подпоследовательностей:
Создайте хеш-таблицу для отслеживания количества подпоследовательностей, которые могут быть продолжены для каждого элемента.
Пройдите по каждому элементу в массиве и выполните следующие действия:
Если элемент можно добавить к существующей подпоследовательности (проверяя хеш-таблицу подпоследовательностей), добавьте его и обновите хеш-таблицу.
Если элемент нельзя добавить к существующей подпоследовательности, начните новую последовательность длиной 3 или более элементов.
Если ни одно из условий не выполнено, верните false.
3⃣ Проверка результата:
Верните true, если все элементы успешно распределены по подпоследовательностям.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан отсортированный в неубывающем порядке массив целых чисел nums.
Определите, можно ли разделить nums на одну или несколько подпоследовательностей так, чтобы выполнялись оба следующих условия:
Каждая подпоследовательность является последовательностью последовательных возрастающих чисел (то есть каждое целое число на 1 больше предыдущего).
Все подпоследовательности имеют длину 3 или более.
Верните true, если можно разделить nums согласно вышеуказанным условиям, или false в противном случае.
Подпоследовательность массива — это новый массив, который формируется из исходного массива путем удаления некоторых (может быть, ни одного) элементов без нарушения относительных позиций оставшихся элементов. (например, [1,3,5] является подпоследовательностью [1,2,3,4,5], тогда как [1,3,2] не является).
Пример:
Input: nums = [1,2,3,3,4,5]
Output: true
Создайте хеш-таблицу для подсчета количества вхождений каждого элемента в массиве nums.
Создайте хеш-таблицу для отслеживания количества подпоследовательностей, которые могут быть продолжены для каждого элемента.
Пройдите по каждому элементу в массиве и выполните следующие действия:
Если элемент можно добавить к существующей подпоследовательности (проверяя хеш-таблицу подпоследовательностей), добавьте его и обновите хеш-таблицу.
Если элемент нельзя добавить к существующей подпоследовательности, начните новую последовательность длиной 3 или более элементов.
Если ни одно из условий не выполнено, верните false.
Верните true, если все элементы успешно распределены по подпоследовательностям.
class Solution {
function isPossible($nums) {
$freq = array_count_values($nums);
$need = [];
foreach ($nums as $num) {
if ($freq[$num] == 0) continue;
if (isset($need[$num]) && $need[$num] > 0) {
$need[$num]--;
$need[$num + 1] = isset($need[$num + 1]) ? $need[$num + 1] + 1 : 1;
} elseif (isset($freq[$num + 1]) && $freq[$num + 1] > 0 && isset($freq[$num + 2]) && $freq[$num + 2] > 0) {
$freq[$num + 1]--;
$freq[$num + 2]--;
$need[$num + 3] = isset($need[$num + 3]) ? $need[$num + 3] + 1 : 1;
} else {
return false;
}
$freq[$num]--;
}
return true;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 679. 24 Game
Сложность: hard
Дан массив целых чисел cards длиной 4. У вас есть четыре карты, каждая из которых содержит число в диапазоне от 1 до 9. Вам нужно расположить числа на этих картах в математическом выражении, используя операторы ['+', '-', '*', '/'] и скобки '(' и ')' так, чтобы получить значение 24.
Вы ограничены следующими правилами:
Оператор деления '/' представляет собой реальное деление, а не целочисленное деление.
Например, 4 / (1 - 2 / 3) = 4 / (1 / 3) = 12.
Каждая операция выполняется между двумя числами. В частности, мы не можем использовать '-' как унарный оператор.
Например, если cards = [1, 1, 1, 1], выражение "-1 - 1 - 1 - 1" не допускается.
Вы не можете объединять числа вместе.
Например, если cards = [1, 2, 1, 2], выражение "12 + 12" недопустимо.
Вернуть true, если вы можете получить такое выражение, которое оценивается в 24, и false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣ Создайте функцию generatePossibleResults(a, b), которая возвращает массив результатов всех возможных математических операций над двумя числами.
2⃣ Создайте функцию checkIfResultReached(list), чтобы проверить, можем ли мы достичь результата 24, используя текущий массив list. Сначала проверьте базовые условия: если размер массива равен 1, верните true, если результат равен 24, иначе верните false.
3⃣ Если размер массива больше 1, выберите любые два числа из списка, выполните все математические операции над ними, создайте новый список с обновленными элементами и снова вызовите рекурсивную функцию с этим новым списком. Если ни одна комбинация не приводит к результату 24, верните false. Вызовите checkIfResultReached с исходным списком карт.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан массив целых чисел cards длиной 4. У вас есть четыре карты, каждая из которых содержит число в диапазоне от 1 до 9. Вам нужно расположить числа на этих картах в математическом выражении, используя операторы ['+', '-', '*', '/'] и скобки '(' и ')' так, чтобы получить значение 24.
Вы ограничены следующими правилами:
Оператор деления '/' представляет собой реальное деление, а не целочисленное деление.
Например, 4 / (1 - 2 / 3) = 4 / (1 / 3) = 12.
Каждая операция выполняется между двумя числами. В частности, мы не можем использовать '-' как унарный оператор.
Например, если cards = [1, 1, 1, 1], выражение "-1 - 1 - 1 - 1" не допускается.
Вы не можете объединять числа вместе.
Например, если cards = [1, 2, 1, 2], выражение "12 + 12" недопустимо.
Вернуть true, если вы можете получить такое выражение, которое оценивается в 24, и false в противном случае.
Пример:
Input: cards = [4,1,8,7]
Output: true
Explanation: (8-4) * (7-1) = 24
class Solution {
function generatePossibleResults($a, $b) {
$res = [$a + $b, $a - $b, $b - $a, $a * $b];
if ($a != 0) $res[] = $b / $a;
if ($b != 0) $res[] = $a / $b;
return $res;
}
function checkIfResultReached($list) {
if (count($list) == 1) return abs($list[0] - 24) <= 0.1;
for ($i = 0; $i < count($list); $i++) {
for ($j = $i + 1; $j < count($list); $j++) {
$newList = [];
for ($k = 0; $k < count($list); $k++) {
if ($k != $i && $k != $j) $newList[] = $list[$k];
}
foreach ($this->generatePossibleResults($list[$i], $list[$j]) as $res) {
$newList[] = $res;
if ($this->checkIfResultReached($newList)) return true;
array_pop($newList);
}
}
}
return false;
}
function judgePoint24($cards) {
return $this->checkIfResultReached(array_map('floatval', $cards));
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 847. Shortest Path Visiting All Nodes
Сложность: hard
У вас есть неориентированный связный граф из n узлов, пронумерованных от 0 до n - 1. Вам дан массив graph, где graph[i] — это список всех узлов, соединенных с узлом i ребром.
Верните длину кратчайшего пути, который посещает каждый узел. Вы можете начать и закончить в любом узле, вы можете несколько раз посещать узлы и использовать ребра повторно.
Пример:
👨💻 Алгоритм:
1⃣ Если граф содержит только один узел, верните 0, так как мы можем начать и закончить в этом узле, не делая никаких шагов.
2⃣ Инициализируйте необходимые переменные: количество узлов n, маску окончания endingMask, структуру данных seen для предотвращения циклов, очередь для выполнения BFS и счетчик шагов steps.
3⃣ Заполните очередь и seen начальными состояниями (начало в каждом узле с маской, указывающей, что посещен только данный узел), затем выполните BFS для поиска кратчайшего пути, который посещает все узлы. Если найден путь, возвращайте количество шагов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
У вас есть неориентированный связный граф из n узлов, пронумерованных от 0 до n - 1. Вам дан массив graph, где graph[i] — это список всех узлов, соединенных с узлом i ребром.
Верните длину кратчайшего пути, который посещает каждый узел. Вы можете начать и закончить в любом узле, вы можете несколько раз посещать узлы и использовать ребра повторно.
Пример:
Input: graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
Output: 4
Explanation: One possible path is [0,1,4,2,3]
class Solution {
/**
* @param Integer[][] $graph
* @return Integer
*/
function shortestPathLength($graph) {
$n = count($graph);
if ($n == 1) return 0;
$endingMask = (1 << $n) - 1;
$seen = array_fill(0, $n, array_fill(0, $endingMask, false));
$queue = [];
for ($i = 0; $i < $n; $i++) {
$queue[] = [$i, 1 << $i];
$seen[$i][1 << $i] = true;
}
$steps = 0;
while (!empty($queue)) {
$nextQueue = [];
foreach ($queue as [$node, $mask]) {
foreach ($graph[$node] as $neighbor) {
$nextMask = $mask | (1 << $neighbor);
if ($nextMask == $endingMask) return 1 + $steps;
if (!$seen[$neighbor][$nextMask]) {
$seen[$neighbor][$nextMask] = true;
$nextQueue[] = [$neighbor, $nextMask];
}
}
}
$steps++;
$queue = $nextQueue;
}
return -1;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1038. Binary Search Tree to Greater Sum Tree
Сложность: medium
Получив корень двоичного дерева поиска (BST), преобразуйте его в большее дерево таким образом, чтобы каждый ключ исходного BST был заменен на исходный ключ плюс сумма всех ключей, превышающих исходный ключ в BST. Напомним, что двоичное дерево поиска - это дерево, удовлетворяющее следующим ограничениям: левое поддерево узла содержит только узлы с ключами меньше, чем ключ узла. Правое поддерево узла содержит только узлы с ключами больше, чем ключ узла. И левое, и правое поддеревья должны быть двоичными деревьями поиска.
Пример:
👨💻 Алгоритм:
1⃣ Обратный обход in-order:
Пройдите по дереву в порядке "правый, корень, левый" (обратный in-order обход). Это обеспечит посещение узлов в порядке убывания их значений.
2⃣ Накопление суммы:
Во время обхода поддерживайте переменную для хранения накопленной суммы. На каждом узле добавляйте значение узла к накопленной сумме и обновляйте значение узла этой накопленной суммой.
3⃣ Преобразование узлов:
Преобразуйте значение каждого узла в накопленную сумму.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Получив корень двоичного дерева поиска (BST), преобразуйте его в большее дерево таким образом, чтобы каждый ключ исходного BST был заменен на исходный ключ плюс сумма всех ключей, превышающих исходный ключ в BST. Напомним, что двоичное дерево поиска - это дерево, удовлетворяющее следующим ограничениям: левое поддерево узла содержит только узлы с ключами меньше, чем ключ узла. Правое поддерево узла содержит только узлы с ключами больше, чем ключ узла. И левое, и правое поддеревья должны быть двоичными деревьями поиска.
Пример:
Input: root = [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
Output: [30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
Пройдите по дереву в порядке "правый, корень, левый" (обратный in-order обход). Это обеспечит посещение узлов в порядке убывания их значений.
Во время обхода поддерживайте переменную для хранения накопленной суммы. На каждом узле добавляйте значение узла к накопленной сумме и обновляйте значение узла этой накопленной суммой.
Преобразуйте значение каждого узла в накопленную сумму.
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;
}
}
class Solution {
private $sum = 0;
function bstToGst($root) {
$this->reverseInorder($root);
return $root;
}
function reverseInorder($node) {
if ($node === null) return;
$this->reverseInorder($node->right);
$this->sum += $node->val;
$node->val = $this->sum;
$this->reverseInorder($node->left);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 868. Binary Gap
Сложность: easy
Дано положительное целое число n, найдите и верните наибольшее расстояние между любыми двумя соседними единицами в двоичном представлении числа n. Если нет двух соседних единиц, верните 0.
Две единицы считаются соседними, если их разделяют только нули (возможно, никаких нулей нет). Расстояние между двумя единицами — это абсолютная разница между их позициями в битовом представлении. Например, две единицы в "1001" имеют расстояние 3.
Пример:
👨💻 Алгоритм:
1⃣ Создайте список A индексов i, таких что в двоичном представлении числа n i-й бит установлен в 1.
2⃣ Используйте список A, чтобы найти максимальное расстояние между соседними значениями. Для этого пройдите по списку и вычислите разницу между каждым соседним элементом.
3⃣ Верните найденное максимальное расстояние.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано положительное целое число n, найдите и верните наибольшее расстояние между любыми двумя соседними единицами в двоичном представлении числа n. Если нет двух соседних единиц, верните 0.
Две единицы считаются соседними, если их разделяют только нули (возможно, никаких нулей нет). Расстояние между двумя единицами — это абсолютная разница между их позициями в битовом представлении. Например, две единицы в "1001" имеют расстояние 3.
Пример:
Input: n = 22
Output: 2
Explanation: 22 in binary is "10110".
The first adjacent pair of 1's is "10110" with a distance of 2.
The second adjacent pair of 1's is "10110" with a distance of 1.
The answer is the largest of these two distances, which is 2.
Note that "10110" is not a valid pair since there is a 1 separating the two 1's underlined.
class Solution {
function binaryGap($N) {
$A = [];
for ($i = 0; $i < 32; $i++)
if (($N >> $i) & 1) $A[] = $i;
$ans = 0;
for ($i = 0; $i < count($A) - 1; $i++)
$ans = max($ans, $A[$i + 1] - $A[$i]);
return $ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 525. Contiguous Array
Сложность: medium
Дан бинарный массив nums. Верните максимальную длину непрерывного подмассива с равным количеством 0 и 1.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменную count для отслеживания разности между количеством 1 и 0, и переменную max_length для хранения максимальной длины подмассива. Создайте хеш-таблицу map для хранения первых встреч каждого значения count. Добавьте начальное значение (0, -1) в хеш-таблицу.
2⃣ Итеративно пройдите по массиву nums. На каждой итерации обновляйте значение count (увеличивайте на 1 для 1 и уменьшайте на 1 для 0). Если текущее значение count уже существует в хеш-таблице, вычислите длину подмассива между текущим индексом и индексом из хеш-таблицы. Обновите max_length, если текущий подмассив длиннее.
3⃣ Если текущее значение count не существует в хеш-таблице, добавьте его с текущим индексом. После завершения итерации верните max_length.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан бинарный массив nums. Верните максимальную длину непрерывного подмассива с равным количеством 0 и 1.
Пример:
Input: nums = [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.
class Solution {
function findMaxLength($nums) {
$countMap = [0 => -1];
$maxLength = 0;
$count = 0;
for ($i = 0; $i < count($nums); $i++) {
$count += ($nums[$i] == 1 ? 1 : -1);
if (array_key_exists($count, $countMap)) {
$maxLength = max($maxLength, $i - $countMap[$count]);
} else {
$countMap[$count] = $i;
}
}
return $maxLength;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1319. Number of Operations to Make Network Connected
Сложность: medium
Дано n компьютеров, пронумерованных от 0 до n - 1, соединённых Ethernet-кабелями connections, образующими сеть, где connections[i] = [ai, bi] представляет собой соединение между компьютерами ai и bi. Любой компьютер может достичь любого другого компьютера напрямую или косвенно через сеть.
Вам даны начальные соединения сети. Вы можете извлекать определённые кабели между двумя напрямую соединёнными компьютерами и размещать их между любыми парами несоединённых компьютеров, чтобы сделать их напрямую соединёнными.
Верните минимальное количество раз, которое необходимо сделать это, чтобы соединить все компьютеры. Если это невозможно, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Проверьте размер connections. Если он меньше n - 1, у нас недостаточно ребер, чтобы соединить весь граф. В этом случае возвращаем -1.
2⃣ Создайте список смежности с помощью connections, где adj[x] содержит всех соседей узла x. Создайте целое число numberOfConnectedComponents, которое хранит количество компонент связности в графе. Инициализируйте его значением 0.
3⃣ Создайте массив visit длиной n для отслеживания посещенных узлов. Пройдите по всем узлам, и для каждого узла i проверьте, был ли он посещен. Если узел i не был посещен, увеличьте numberOfConnectedComponents на 1 и начните обход DFS:
Используйте функцию dfs для выполнения обхода. Для каждого вызова передавайте узел, ребра и visit в качестве параметров, начиная с узла i.
Отметьте узел как посещенный.
Пройдитесь по всем соседям узла. Если какой-либо сосед еще не был посещен, рекурсивно вызовите dfs с этим соседом в качестве узла.
Верните numberOfConnectedComponents - 1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано n компьютеров, пронумерованных от 0 до n - 1, соединённых Ethernet-кабелями connections, образующими сеть, где connections[i] = [ai, bi] представляет собой соединение между компьютерами ai и bi. Любой компьютер может достичь любого другого компьютера напрямую или косвенно через сеть.
Вам даны начальные соединения сети. Вы можете извлекать определённые кабели между двумя напрямую соединёнными компьютерами и размещать их между любыми парами несоединённых компьютеров, чтобы сделать их напрямую соединёнными.
Верните минимальное количество раз, которое необходимо сделать это, чтобы соединить все компьютеры. Если это невозможно, верните -1.
Пример:
Input: n = 4, connections = [[0,1],[0,2],[1,2]]
Output: 1
Explanation: Remove cable between computer 1 and 2 and place between computers 1 and 3.
Используйте функцию dfs для выполнения обхода. Для каждого вызова передавайте узел, ребра и visit в качестве параметров, начиная с узла i.
Отметьте узел как посещенный.
Пройдитесь по всем соседям узла. Если какой-либо сосед еще не был посещен, рекурсивно вызовите dfs с этим соседом в качестве узла.
Верните numberOfConnectedComponents - 1.
class Solution {
private function dfs($node, $adj, &$visit) {
$visit[$node] = true;
if (!isset($adj[$node])) {
return;
}
foreach ($adj[$node] as $neighbor) {
if (!$visit[$neighbor]) {
$visit[$neighbor] = true;
$this->dfs($neighbor, $adj, $visit);
}
}
}
function makeConnected($n, $connections) {
if (count($connections) < $n - 1) {
return -1;
}
$adj = [];
foreach ($connections as $connection) {
$adj[$connection[0]][] = $connection[1];
$adj[$connection[1]][] = $connection[0];
}
$numberOfConnectedComponents = 0;
$visit = array_fill(0, $n, false);
for ($i = 0; $i < $n; $i++) {
if (!$visit[$i]) {
$numberOfConnectedComponents++;
$this->dfs($i, $adj, $visit);
}
}
return $numberOfConnectedComponents - 1;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 360. Sort Transformed Array
Сложность: medium
Дан отсортированный массив целых чисел nums и три целых числа a, b и c. Примените квадратичную функцию вида f(x) = ax^2 + bx + c к каждому элементу nums[i] в массиве и верните массив в отсортированном порядке.
Пример:
👨💻 Алгоритм:
1⃣ Преобразование и сортировка
Преобразуем каждый элемент массива nums по квадратичной функции f(x) = ax^2 + bx + c и сохраняем результаты в массив transformed. Используем алгоритм поразрядной сортировки для сортировки массива transformed.
2⃣ Поразрядная сортировка
Находим максимальное значение по модулю в массиве для определения количества цифр. Применяем поразрядную сортировку к массиву transformed.
3⃣ Сортировка по цифре
Для каждой цифры (разряда) используем подсчет для сортировки массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан отсортированный массив целых чисел nums и три целых числа a, b и c. Примените квадратичную функцию вида f(x) = ax^2 + bx + c к каждому элементу nums[i] в массиве и верните массив в отсортированном порядке.
Пример:
Input: nums = [-4,-2,2,4], a = 1, b = 3, c = 5
Output: [3,9,15,33]
Преобразуем каждый элемент массива nums по квадратичной функции f(x) = ax^2 + bx + c и сохраняем результаты в массив transformed. Используем алгоритм поразрядной сортировки для сортировки массива transformed.
Находим максимальное значение по модулю в массиве для определения количества цифр. Применяем поразрядную сортировку к массиву transformed.
Для каждой цифры (разряда) используем подсчет для сортировки массива.
class Solution {
function sortTransformedArray($nums, $a, $b, $c) {
$transformed = array_map(function($x) use ($a, $b, $c) {
return $a * $x * $x + $b * $x + $c;
}, $nums);
$this->radixSort($transformed);
return $transformed;
}
private function radixSort(&$array) {
$maxElement = max(array_map('abs', $array));
$placeValue = 1;
while ($maxElement / $placeValue > 0) {
$this->countingSortByDigit($array, $placeValue);
$placeValue *= 10;
}
$negatives = array_filter($array, function($x) { return $x < 0; });
$positives = array_filter($array, function($x) { return $x >= 0; });
sort($negatives);
sort($positives);
$array = array_merge($negatives, $positives);
}
private function countingSortByDigit(&$array, $placeValue) {
$n = count($array);
$output = array_fill(0, $n, 0);
$count = array_fill(0, 10, 0);
foreach ($array as $num) {
$digit = (int)(abs($num) / $placeValue) % 10;
$count[$digit]++;
}
for ($i = 1; $i < 10; $i++) {
$count[$i] += $count[$i - 1];
}
for ($i = $n - 1; $i >= 0; $i--) {
$num = $array[$i];
$digit = (int)(abs($num) / $placeValue) % 10;
$output[$count[$digit] - 1] = $num;
$count[$digit]--;
}
for ($i = 0; $i < $n; $i++) {
$array[$i] = $output[$i];
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 121. Best Time to Buy and Sell Stock
Сложность: easy
Вам дан массив цен, где prices[i] является ценой данной акции в i-й день.
Ваша задача — максимизировать вашу прибыль, выбрав один день для покупки акции и другой день в будущем для ее продажи.
Верните максимальную прибыль, которую вы можете получить от этой операции. Если прибыль получить невозможно, верните 0.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируем minPrice значением PHP_INT_MAX, maxProfit — 0.
2⃣ Проходим по всем ценам:
Если текущая цена меньше minPrice, обновляем minPrice.
Если текущая прибыль (price - minPrice) больше maxProfit, обновляем maxProfit.
3⃣ Возвращаем maxProfit.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам дан массив цен, где prices[i] является ценой данной акции в i-й день.
Ваша задача — максимизировать вашу прибыль, выбрав один день для покупки акции и другой день в будущем для ее продажи.
Верните максимальную прибыль, которую вы можете получить от этой операции. Если прибыль получить невозможно, верните 0.
Пример:
Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.
Если текущая цена меньше minPrice, обновляем minPrice.
Если текущая прибыль (price - minPrice) больше maxProfit, обновляем maxProfit.
class Solution {
public function maxProfit($prices) {
$minPrice = PHP_INT_MAX;
$maxProfit = 0;
foreach ($prices as $price) {
if ($price < $minPrice) {
$minPrice = $price;
} elseif ($price - $minPrice > $maxProfit) {
$maxProfit = $price - $minPrice;
}
}
return $maxProfit;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 971. Flip Binary Tree To Match Preorder Traversal
Сложность: medium
Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order.
Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект:
Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage.
Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1].
Пример:
👨💻 Алгоритм:
1⃣ Выполните поиск в глубину. Если в каком-либо узле значение узла не соответствует значению в voyage, верните [-1].
2⃣ Иначе определите, когда нужно перевернуть: если следующее ожидаемое число в voyage (voyage[i]) отличается от следующего потомка.
3⃣ Переверните узел, добавьте его значение в список перевернутых узлов и продолжите обход дерева, пока весь порядок обхода pre-order не будет соответствовать voyage.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order.
Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект:
Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage.
Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1].
Пример:
Input: root = [1,2], voyage = [2,1]
Output: [-1]
Explanation: It is impossible to flip the nodes such that the pre-order traversal matches voyage.
class Solution {
public $flipped;
public $index;
public $voyage;
function flipMatchVoyage($root, $voyage) {
$this->flipped = [];
$this->index = 0;
$this->voyage = $voyage;
$this->dfs($root);
if (!empty($this->flipped) && $this->flipped[0] == -1) {
return [-1];
}
return $this->flipped;
}
function dfs($node) {
if ($node !== null) {
if ($node->val != $this->voyage[$this->index++]) {
$this->flipped = [-1];
return;
}
if ($this->index < count($this->voyage) && $node->left !== null && $node->left->val != $this->voyage[$this->index]) {
$this->flipped[] = $node->val;
$this->dfs($node->right);
$this->dfs($node->left);
} else {
$this->dfs($node->left);
$this->dfs($node->right);
}
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1356. Sort Integers by The Number of 1 Bits
Сложность: easy
Дан целочисленный массив arr. Отсортируйте целые числа в массиве по возрастанию числа единиц в их двоичном представлении, а в случае, если у двух или более чисел одинаковое количество единиц, отсортируйте их по возрастанию.
Верните массив после сортировки.
Пример:
👨💻 Алгоритм:
1⃣ Создание функции для подсчета единиц:
Создайте функцию, которая принимает целое число и возвращает количество единиц в его двоичном представлении.
2⃣ Сортировка массива:
Используйте встроенную функцию сортировки, передавая ей пользовательскую функцию сравнения, которая использует количество единиц в двоичном представлении чисел для сортировки. Если количество единиц одинаковое, используйте само число для сортировки.
3⃣ Возврат отсортированного массива:
Верните отсортированный массив.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан целочисленный массив arr. Отсортируйте целые числа в массиве по возрастанию числа единиц в их двоичном представлении, а в случае, если у двух или более чисел одинаковое количество единиц, отсортируйте их по возрастанию.
Верните массив после сортировки.
Пример:
Input: arr = [1024,512,256,128,64,32,16,8,4,2,1]
Output: [1,2,4,8,16,32,64,128,256,512,1024]
Explantion: All integers have 1 bit in the binary representation, you should just sort them in ascending order.
Создайте функцию, которая принимает целое число и возвращает количество единиц в его двоичном представлении.
Используйте встроенную функцию сортировки, передавая ей пользовательскую функцию сравнения, которая использует количество единиц в двоичном представлении чисел для сортировки. Если количество единиц одинаковое, используйте само число для сортировки.
Верните отсортированный массив.
class Solution {
function sortByBits($arr) {
usort($arr, function($a, $b) {
$countA = substr_count(decbin($a), '1');
$countB = substr_count(decbin($b), '1');
return $countA === $countB ? $a - $b : $countA - $countB;
});
return $arr;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 273. Integer to English Words
Сложность: hard
Преобразуйте неотрицательное целое число num в его словесное представление на английском языке.
Пример:
👨💻 Алгоритм:
1⃣ Обработка чисел до 20 и кратных 10 до 90:
Создать массивы или словари для чисел от 1 до 19 и для кратных 10 от 20 до 90.
Если число попадает в эти диапазоны, сразу вернуть соответствующее словесное представление.
2⃣ Обработка сотен, тысяч, миллионов и миллиардов:
Разделить число на группы по три цифры (единицы, тысячи, миллионы, миллиарды).
Для каждой группы сформировать словесное представление с использованием рекурсивной функции для чисел от 1 до 999.
3⃣ Формирование окончательного результата:
Собрать словесное представление всех групп, добавив соответствующие суффиксы (тысячи, миллионы, миллиарды).
Соединить все части в одну строку, удалив лишние пробелы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Преобразуйте неотрицательное целое число num в его словесное представление на английском языке.
Пример:
Input: num = 123
Output: "One Hundred Twenty Three"
Создать массивы или словари для чисел от 1 до 19 и для кратных 10 от 20 до 90.
Если число попадает в эти диапазоны, сразу вернуть соответствующее словесное представление.
Разделить число на группы по три цифры (единицы, тысячи, миллионы, миллиарды).
Для каждой группы сформировать словесное представление с использованием рекурсивной функции для чисел от 1 до 999.
Собрать словесное представление всех групп, добавив соответствующие суффиксы (тысячи, миллионы, миллиарды).
Соединить все части в одну строку, удалив лишние пробелы.
class Solution {
private $belowTwenty = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"];
private $tens = ["", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
private $thousands = ["", "Thousand", "Million", "Billion"];
function numberToWords($num) {
if ($num == 0) return "Zero";
$result = "";
$i = 0;
while ($num > 0) {
if ($num % 1000 != 0) {
$result = $this->helper($num % 1000) . $this->thousands[$i] . " " . $result;
}
$num = intval($num / 1000);
$i++;
}
return trim($result);
}
private function helper($num) {
if ($num == 0) return "";
else if ($num < 20) return $this->belowTwenty[$num] . " ";
else if ($num < 100) return $this->tens[intval($num / 10)] . " " . $this->helper($num % 10);
else return $this->belowTwenty[intval($num / 100)] . " Hundred " . $this->helper($num % 100);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1275. Find Winner on a Tic Tac Toe Game
Сложность: easy
В игру "Крестики-нолики" играют два игрока A и B на сетке 3 x 3. Правила игры "Крестики-нолики" таковы: игроки по очереди помещают символы в пустые квадраты ' '. Первый игрок A всегда помещает символы "X", а второй игрок B - "O". Символы "X" и "O" всегда помещаются в пустые квадраты, а не в заполненные.
Игра заканчивается, когда три одинаковых (непустых) символа заполняют любую строку, столбец или диагональ. Игра также заканчивается, если все клетки непустые. Больше ходов не может быть сыграно, если игра закончена. Учитывая двумерный целочисленный массив moves, где moves[i] = [rowi, coli] указывает, что i-й ход будет сыгран на сетке[rowi][coli]. верните победителя игры, если он существует (A или B). Если игра закончилась вничью, верните "Ничья". Если еще есть ходы для игры, верните "Pending". Можно предположить, что ходы действительны (т.е. соответствуют правилам игры в Крестики-нолики), сетка изначально пуста, и A будет играть первым.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте пустую 3x3 сетку.
2⃣ Пройдите по списку ходов и обновите сетку в соответствии с ходами игроков A и B.
3⃣ После каждого хода проверяйте, есть ли победитель. Если все ходы сделаны и нет победителя, проверьте, завершена ли игра вничью или еще есть ходы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
В игру "Крестики-нолики" играют два игрока A и B на сетке 3 x 3. Правила игры "Крестики-нолики" таковы: игроки по очереди помещают символы в пустые квадраты ' '. Первый игрок A всегда помещает символы "X", а второй игрок B - "O". Символы "X" и "O" всегда помещаются в пустые квадраты, а не в заполненные.
Игра заканчивается, когда три одинаковых (непустых) символа заполняют любую строку, столбец или диагональ. Игра также заканчивается, если все клетки непустые. Больше ходов не может быть сыграно, если игра закончена. Учитывая двумерный целочисленный массив moves, где moves[i] = [rowi, coli] указывает, что i-й ход будет сыгран на сетке[rowi][coli]. верните победителя игры, если он существует (A или B). Если игра закончилась вничью, верните "Ничья". Если еще есть ходы для игры, верните "Pending". Можно предположить, что ходы действительны (т.е. соответствуют правилам игры в Крестики-нолики), сетка изначально пуста, и A будет играть первым.
Пример:
Input: moves = [[0,0],[2,0],[1,1],[2,1],[2,2]]
Output: "A"
function tictactoe($moves) {
$grid = array_fill(0, 3, array_fill(0, 3, ''));
for ($i = 0; $i < count($moves); $i++) {
$r = $moves[$i][0];
$c = $moves[$i][1];
$grid[$r][$c] = $i % 2 == 0 ? 'X' : 'O';
}
for ($i = 0; $i < 3; $i++) {
if ($grid[$i][0] == $grid[$i][1] && $grid[$i][1] == $grid[$i][2] && $grid[$i][0] != '')
return $grid[$i][0] == 'X' ? 'A' : 'B';
if ($grid[0][$i] == $grid[1][$i] && $grid[1][$i] == $grid[2][$i] && $grid[0][$i] != '')
return $grid[0][$i] == 'X' ? 'A' : 'B';
}
if ($grid[0][0] == $grid[1][1] && $grid[1][1] == $grid[2][2] && $grid[0][0] != '')
return $grid[0][0] == 'X' ? 'A' : 'B';
if ($grid[0][2] == $grid[1][1] && $grid[1][1] == $grid[2][0] && $grid[0][2] != '')
return $grid[0][2] == 'X' ? 'A' : 'B';
return count($moves) == 9 ? 'Draw' : 'Pending';
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 421. Maximum XOR of Two Numbers in an Array
Сложность: medium
Дан целочисленный массив nums, верните максимальный результат nums[i] XOR nums[j], где 0 <= i <= j < n.
Пример:
👨💻 Алгоритм:
1⃣ Вычислите количество битов L для использования. Это длина максимального числа в двоичном представлении. Инициализируйте max_xor = 0.
2⃣ Запустите цикл от i = L−1 до i = 0 (от самого левого бита L−1 до самого правого бита 0):
Сдвигайте max_xor влево, чтобы освободить следующий бит.
Инициализируйте переменную curr_xor = max_xor | 1, установив 1 в самом правом бите max_xor. Теперь проверьте, можно ли выполнить curr_xor, используя доступные префиксы.
3⃣ Вычислите все возможные префиксы длины L−i, итерируя по nums:
Поместите в HashSet префиксы префикс текущего числа длиной L−i: num >> i.
Итерируйте по всем префиксам и проверьте, можно ли выполнить curr_xor, используя два из них: p1 ^ p2 == curr_xor. Используя свойство самопреобразования XOR p1 ^ p2 ^ p2 = p1, можно переписать это как p1 == curr_xor ^ p2 и просто проверить для каждого p, если curr_xor ^ p есть в префиксах. Если так, установите max_xor равным curr_xor, т.е. установите 1-бит в самом правом бите. В противном случае, пусть max_xor оставит 0-бит в самом правом бите.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан целочисленный массив nums, верните максимальный результат nums[i] XOR nums[j], где 0 <= i <= j < n.
Пример:
Input: nums = [3,10,5,25,2,8]
Output: 28
Explanation: The maximum result is 5 XOR 25 = 28.
Сдвигайте max_xor влево, чтобы освободить следующий бит.
Инициализируйте переменную curr_xor = max_xor | 1, установив 1 в самом правом бите max_xor. Теперь проверьте, можно ли выполнить curr_xor, используя доступные префиксы.
Поместите в HashSet префиксы префикс текущего числа длиной L−i: num >> i.
Итерируйте по всем префиксам и проверьте, можно ли выполнить curr_xor, используя два из них: p1 ^ p2 == curr_xor. Используя свойство самопреобразования XOR p1 ^ p2 ^ p2 = p1, можно переписать это как p1 == curr_xor ^ p2 и просто проверить для каждого p, если curr_xor ^ p есть в префиксах. Если так, установите max_xor равным curr_xor, т.е. установите 1-бит в самом правом бите. В противном случае, пусть max_xor оставит 0-бит в самом правом бите.
class Solution {
function findMaximumXOR($nums) {
$maxNum = $nums[0];
foreach ($nums as $num) {
if ($num > $maxNum) {
$maxNum = $num;
}
}
$L = strlen(decbin($maxNum));
$maxXor = 0;
for ($i = $L - 1; $i >= 0; $i--) {
$maxXor <<= 1;
$currXor = $maxXor | 1;
$prefixes = [];
foreach ($nums as $num) {
$prefixes[$num >> $i] = true;
}
foreach ($prefixes as $p => $true) {
if (isset($prefixes[$currXor ^ $p])) {
$maxXor = $currXor;
break;
}
}
}
return $maxXor;
}
}
?>Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 269. Alien Dictionary
Сложность: hard
Есть новый инопланетный язык, который использует английский алфавит. Однако порядок букв в нем неизвестен.
Вам дан список строк words из словаря инопланетного языка. Утверждается, что строки в words отсортированы лексикографически по правилам этого нового языка.
Если это утверждение неверно и данное расположение строк в words не может соответствовать никакому порядку букв, верните "".
В противном случае верните строку из уникальных букв нового инопланетного языка, отсортированных в лексикографическом порядке по правилам нового языка. Если существует несколько решений, верните любое из них.
Пример:
👨💻 Алгоритм:
1⃣ Извлечение отношений порядка и создание списков смежности:
Извлечь отношения порядка между буквами из слов.
Вставить их в список смежности, обрабатывая случаи, когда одно слово является префиксом другого.
2⃣ Подсчет числа входящих ребер:
Подсчитать количество входящих ребер (in-degree) для каждой буквы.
Построить исходящий список смежности и одновременно считать входящие ребра для каждой буквы.
3⃣ Обход в ширину (BFS):
Инициализировать очередь буквами с нулевым in-degree.
Выполнять BFS, добавляя буквы в результат, когда их in-degree становится нулевым.
Продолжать до тех пор, пока очередь не станет пустой.
Проверить наличие циклов и вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Есть новый инопланетный язык, который использует английский алфавит. Однако порядок букв в нем неизвестен.
Вам дан список строк words из словаря инопланетного языка. Утверждается, что строки в words отсортированы лексикографически по правилам этого нового языка.
Если это утверждение неверно и данное расположение строк в words не может соответствовать никакому порядку букв, верните "".
В противном случае верните строку из уникальных букв нового инопланетного языка, отсортированных в лексикографическом порядке по правилам нового языка. Если существует несколько решений, верните любое из них.
Пример:
Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"
Извлечь отношения порядка между буквами из слов.
Вставить их в список смежности, обрабатывая случаи, когда одно слово является префиксом другого.
Подсчитать количество входящих ребер (in-degree) для каждой буквы.
Построить исходящий список смежности и одновременно считать входящие ребра для каждой буквы.
Инициализировать очередь буквами с нулевым in-degree.
Выполнять BFS, добавляя буквы в результат, когда их in-degree становится нулевым.
Продолжать до тех пор, пока очередь не станет пустой.
Проверить наличие циклов и вернуть результат.
function alienOrder($words) {
$adjList = [];
$inDegree = [];
foreach ($words as $word) {
foreach (str_split($word) as $char) {
$inDegree[$char] = 0;
}
}
for ($i = 0; $i < count($words) - 1; $i++) {
$firstWord = $words[$i];
$secondWord = $words[$i + 1];
for ($j = 0; $j < min(strlen($firstWord), strlen($secondWord)); $j++) {
$c = $firstWord[$j];
$d = $secondWord[$j];
if ($c !== $d) {
if (!isset($adjList[$c])) {
$adjList[$c] = [];
}
if (!in_array($d, $adjList[$c])) {
$adjList[$c][] = $d;
$inDegree[$d]++;
}
break;
}
}
if (strlen($secondWord) < strlen($firstWord) && strpos($firstWord, $secondWord) === 0) {
return "";
}
}
$output = [];
$queue = [];
foreach ($inDegree as $char => $degree) {
if ($degree == 0) {
$queue[] = $char;
}
}
while (!empty($queue)) {
$c = array_shift($queue);
$output[] = $c;
if (isset($adjList[$c])) {
foreach ($adjList[$c] as $d) {
$inDegree[$d]--;
if ($inDegree[$d] == 0) {
$queue[] = $d;
}
}
}
}
if (count($output) < count($inDegree)) {
return "";
}
return implode("", $output);
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 587. Erect the Fence
Сложность: hard
Вам дан массив trees, где trees[i] = [xi, yi] представляет местоположение дерева в саду.
Оградите весь сад с использованием минимальной длины веревки, так как это дорого. Сад хорошо огорожен только в том случае, если все деревья окружены.
Верните координаты деревьев, которые находятся точно на периметре ограды. Вы можете вернуть ответ в любом порядке.
Пример:
👨💻 Алгоритм:
1⃣ Сортировка точек и построение нижней оболочки:
Отсортируйте точки по их x-координатам, а в случае совпадения x-координат, по y-координатам.
Постройте нижнюю оболочку, добавляя точки к оболочке и удаляя последние точки, если они не образуют против часовой стрелки поворот.
2⃣ Построение верхней оболочки:
Пройдитесь по точкам в обратном порядке, чтобы построить верхнюю оболочку.
Добавляйте точки к оболочке и удаляйте последние точки, если они не образуют против часовой стрелки поворот.
3⃣ Удаление дублирующих элементов и возврат результата:
Используйте HashSet, чтобы удалить дублирующиеся точки из стека.
Преобразуйте результат в массив и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дан массив trees, где trees[i] = [xi, yi] представляет местоположение дерева в саду.
Оградите весь сад с использованием минимальной длины веревки, так как это дорого. Сад хорошо огорожен только в том случае, если все деревья окружены.
Верните координаты деревьев, которые находятся точно на периметре ограды. Вы можете вернуть ответ в любом порядке.
Пример:
Input: trees = [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]]
Output: [[1,1],[2,0],[4,2],[3,3],[2,4]]
Explanation: All the trees will be on the perimeter of the fence except the tree at [2, 2], which will be inside the fence.
Отсортируйте точки по их x-координатам, а в случае совпадения x-координат, по y-координатам.
Постройте нижнюю оболочку, добавляя точки к оболочке и удаляя последние точки, если они не образуют против часовой стрелки поворот.
Пройдитесь по точкам в обратном порядке, чтобы построить верхнюю оболочку.
Добавляйте точки к оболочке и удаляйте последние точки, если они не образуют против часовой стрелки поворот.
Используйте HashSet, чтобы удалить дублирующиеся точки из стека.
Преобразуйте результат в массив и верните его.
class Solution {
private function orientation($p, $q, $r) {
return ($q[1] - $p[1]) * ($r[0] - $q[0]) - ($q[0] - $p[0]) * ($r[1] - $q[1]);
}
function outerTrees($points) {
usort($points, function($a, $b) {
return $a[0] === $b[0] ? $a[1] - $b[1] : $a[0] - $b[0];
});
$hull = [];
foreach ($points as $point) {
while (count($hull) >= 2 && $this->orientation($hull[count($hull) - 2], $hull[count($hull) - 1], $point) > 0) {
array_pop($hull);
}
$hull[] = $point;
}
array_pop($hull);
for ($i = count($points) - 1; $i >= 0; $i--) {
while (count($hull) >= 2 && $this->orientation($hull[count($hull) - 2], $hull[count($hull) - 1], $points[$i]) > 0) {
array_pop($hull);
}
$hull[] = $points[$i];
}
$uniqueHull = [];
foreach ($hull as $h) {
$uniqueHull[implode(',', $h)] = $h;
}
return array_values($uniqueHull);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 600. Non-negative Integers without Consecutive Ones
Сложность: Hard
Дано положительное целое число n, верните количество чисел в диапазоне [0, n], бинарные представления которых не содержат последовательных единиц.
Пример:
👨💻 Алгоритм:
1⃣ Простой метод заключается в переборе всех чисел от 1 до num. Для каждого текущего выбранного числа проверяем все соседние позиции, чтобы выяснить, содержит ли число две последовательные единицы. Если не содержит, увеличиваем количество чисел без последовательных единиц.
2⃣ Чтобы проверить, существует ли 1 на позиции x (считая от младшего значащего бита), в текущем числе n, поступаем следующим образом. Сдвигаем двоичную 1 x−1 раз влево, чтобы получить число y, которое имеет 1 только на x-й позиции. Логическое И числа n и y даст результат 1 только если n содержит 1 на позиции x.
3⃣ В конце подсчитываем и возвращаем количество чисел в диапазоне [0, n], не содержащих последовательных единиц.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: Hard
Дано положительное целое число n, верните количество чисел в диапазоне [0, n], бинарные представления которых не содержат последовательных единиц.
Пример:
Input: n = 5
Output: 5
Explanation:
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
class Solution {
function findIntegers($num) {
$count = 0;
for ($i = 0; $i <= $num; $i++) {
if ($this->check($i)) {
$count++;
}
}
return $count;
}
function check($n) {
$i = 31;
while ($i > 0) {
if (($n & (1 << $i)) != 0 && ($n & (1 << ($i - 1))) != 0) {
return false;
}
$i--;
}
return true;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 401. Binary Watch
Сложность: easy
Бинарные часы имеют 4 светодиода сверху для представления часов (0-11) и 6 светодиодов снизу для представления минут (0-59). Каждый светодиод представляет ноль или единицу, при этом младший разряд находится справа.
Пример:
👨💻 Алгоритм:
1⃣ Генерация всех возможных комбинаций:
Переберите все возможные значения для часов и минут.
Используйте битовые операции для подсчета количества единиц в бинарном представлении числа.
2⃣ Проверка количества горящих светодиодов:
Для каждой комбинации проверьте, соответствует ли сумма единиц в бинарном представлении часов и минут заданному количеству горящих светодиодов.
3⃣ Форматирование результата:
Если комбинация часов и минут соответствует условию, отформатируйте их в виде строки "часы:минуты" и добавьте в список результатов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Бинарные часы имеют 4 светодиода сверху для представления часов (0-11) и 6 светодиодов снизу для представления минут (0-59). Каждый светодиод представляет ноль или единицу, при этом младший разряд находится справа.
Пример:
Input: turnedOn = 1
Output: ["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]
Переберите все возможные значения для часов и минут.
Используйте битовые операции для подсчета количества единиц в бинарном представлении числа.
Для каждой комбинации проверьте, соответствует ли сумма единиц в бинарном представлении часов и минут заданному количеству горящих светодиодов.
Если комбинация часов и минут соответствует условию, отформатируйте их в виде строки "часы:минуты" и добавьте в список результатов.
class Solution {
function readBinaryWatch($turnedOn) {
$results = [];
for ($h = 0; $h < 12; $h++) {
for ($m = 0; $m < 60; $m++) {
if (substr_count(decbin($h), '1') + substr_count(decbin($m), '1') == $turnedOn) {
$results[] = sprintf("%d:%02d", $h, $m);
}
}
}
return $results;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2