C# | LeetCode
Open in Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv
Show more3 194
Subscribers
No data24 hours
-37 days
-2830 days
Posts Archive
3 194
Задача: 850. Rectangle Area II
Сложность: hard
Вам дан двумерный массив прямоугольников, выровненных по осям. Каждый прямоугольник[i] = [xi1, yi1, xi2, yi2] обозначает i-й прямоугольник, где (xi1, yi1) — координаты нижнего левого угла, а (xi2, yi2) — координаты верхнего правого угла.
Вычислите общую площадь, покрытую всеми прямоугольниками на плоскости. Любая площадь, покрытая двумя или более прямоугольниками, должна учитываться только один раз.
Верните общую площадь. Поскольку ответ может быть слишком большим, верните его по модулю 10^9 + 7.
Пример:
Input: rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
Output: 6
Explanation: A total area of 6 is covered by all three rectangles, as illustrated in the picture.
From (1,1) to (2,2), the green and red rectangles overlap.
From (1,0) to (2,3), all three rectangles overlap.
👨💻 Алгоритм:
1⃣Переназначьте каждую x координату на 0, 1, 2, .... Аналогично, переназначьте все y координаты.
2⃣Теперь мы имеем задачу, которую можно решить методом грубой силы: для каждого прямоугольника с переназначенными координатами (rx1, ry1, rx2, ry2) заполним сетку grid[x][y] = True для rx1 <= x < rx2 и ry1 <= y < ry2.
3⃣Затем каждая ячейка grid[rx][ry] будет представлять площадь (imapx(rx+1) - imapx(rx)) * (imapy(ry+1) - imapy(ry)), где если x был переназначен на rx, то imapx(rx) = x ("обратная карта x для переназначенного x равна x"), аналогично для imapy.
😎 Решение:
public class Solution {
public int RectangleArea(int[][] rectangles) {
int N = rectangles.Length;
HashSet<int> Xvals = new HashSet<int>();
HashSet<int> Yvals = new HashSet<int>();
foreach (var rec in rectangles) {
Xvals.Add(rec[0]);
Xvals.Add(rec[2]);
Yvals.Add(rec[1]);
Yvals.Add(rec[3]);
}
int[] imapx = Xvals.ToArray();
Array.Sort(imapx);
int[] imapy = Yvals.ToArray();
Array.Sort(imapy);
Dictionary<int, int> mapx = new Dictionary<int, int>();
Dictionary<int, int> mapy = new Dictionary<int, int>();
for (int i = 0; i < imapx.Length; ++i)
mapx[imapx[i]] = i;
for (int i = 0; i < imapy.Length; ++i)
mapy[imapy[i]] = i;
bool[,] grid = new bool[imapx.Length, imapy.Length];
foreach (var rec in rectangles)
for (int x = mapx[rec[0]]; x < mapx[rec[2]]; ++x)
for (int y = mapy[rec[1]]; y < mapy[rec[3]]; ++y)
grid[x, y] = true;
long ans = 0;
for (int x = 0; x < grid.GetLength(0); ++x)
for (int y = 0; y < grid.GetLength(1); ++y)
if (grid[x, y])
ans += (long)(imapx[x + 1] - imapx[x]) * (imapy[y + 1] - imapy[y]);
ans %= 1_000_000_007;
return (int)ans;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
🔍Тестовое собеседование с Senior C# разработчиком уже завтра
15 сентября(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle C# разработчика.
Как это будет:
📂 Александр Моргунов, старший C# разработчик с опытом 7+ лет в Европейских высоконагруженных сервисах, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Александр будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Александру
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для C# разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_csharp_bot
Реклама.
О рекламодателе.
3 194
Задача: 491. Non-decreasing Subsequences
Сложность: medium
Дан массив целых чисел nums. Верните все возможные различные неубывающие подпоследовательности данного массива, содержащие как минимум два элемента. Вы можете вернуть ответ в любом порядке.
Пример:
Input: nums = [4,6,7,7] Output: [[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]👨💻 Алгоритм: 1⃣Инициализация и запуск функции обратного отслеживания Создайте множество для хранения результатов. Создайте список для хранения текущей последовательности. Запустите рекурсивную функцию обратного отслеживания с начальным индексом 0. 2⃣Функция обратного отслеживания Если текущий индекс равен длине массива, проверьте длину текущей последовательности и добавьте её в результат, если она содержит не менее двух элементов. Если текущая последовательность остаётся неубывающей после добавления текущего элемента массива, добавьте этот элемент, вызовите рекурсивную функцию для следующего индекса и удалите элемент из последовательности (обратное отслеживание). Всегда вызывайте рекурсивную функцию для следующего индекса без добавления текущего элемента. 3⃣Возврат результата После завершения всех рекурсивных вызовов преобразуйте множество результатов в список и верните его. 😎 Решение:
public class Solution {
public IList<IList<int>> FindSubsequences(int[] nums) {
var result = new HashSet<IList<int>>();
var sequence = new List<int>();
Backtrack(nums, 0, sequence, result);
return result.ToList();
}
private void Backtrack(int[] nums, int index, List<int> sequence, HashSet<IList<int>> result) {
if (index == nums.Length) {
if (sequence.Count >= 2) {
result.Add(new List<int>(sequence));
}
return;
}
if (sequence.Count == 0 || sequence[sequence.Count - 1] <= nums[index]) {
sequence.Add(nums[index]);
Backtrack(nums, index + 1, sequence, result);
sequence.RemoveAt(sequence.Count - 1);
}
Backtrack(nums, index + 1, sequence, result);
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 136. Single Number
Сложность: easy
Дан непустой массив целых чисел nums, в котором каждый элемент встречается дважды, кроме одного. Найдите этот единственный элемент.
Вы должны реализовать решение с линейной сложностью выполнения и использовать только постоянное дополнительное пространство.
Пример:
Input: nums = [2,2,1] Output: 1👨💻 Алгоритм: 1⃣Переберите все элементы в массиве nums. 2⃣Если какое-то число в nums новое для массива, добавьте его. 3⃣Если какое-то число уже есть в массиве, удалите его. 😎 Решение:
public class Solution {
public int SingleNumber(int[] nums) {
List<int> no_duplicate_list = new List<int>();
foreach (int i in nums) {
if (!no_duplicate_list.Contains(i)) {
no_duplicate_list.Add(i);
} else {
no_duplicate_list.Remove(i);
}
}
return no_duplicate_list[0];
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 1026. Maximum Difference Between Node and Ancestor
Сложность: medium
Учитывая корень бинарного дерева, найдите максимальное значение v, для которого существуют различные вершины a и b, где v = |a.val - b.val| и a является предком b. Вершина a является предком b, если: любой ребенок a равен b или любой ребенок a является предком b.
Пример:
Input: root = [8,3,10,1,6,null,14,null,null,4,7,13]
Output: 7
👨💻 Алгоритм:
1⃣Рекурсивный обход дерева:
Используйте рекурсивную функцию для обхода дерева. Передавайте минимальное и максимальное значения, встреченные на пути от корня к текущему узлу.
2⃣Обновление максимальной разницы:
При посещении каждого узла обновляйте минимальное и максимальное значения. Вычисляйте разницу между текущим значением узла и минимальным и максимальным значениями на пути. Обновляйте максимальную разницу, если текущая разница больше.
3⃣Рекурсивный вызов для детей:
Рекурсивно вызывайте функцию для левого и правого поддерева, передавая обновленные минимальное и максимальное значения.
😎 Решение:
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution {
public int MaxAncestorDiff(TreeNode root) {
return Dfs(root, root.val, root.val);
}
private int Dfs(TreeNode node, int minVal, int maxVal) {
if (node == null) return maxVal - minVal;
minVal = Math.Min(minVal, node.val);
maxVal = Math.Max(maxVal, node.val);
int left = Dfs(node.left, minVal, maxVal);
int right = Dfs(node.right, minVal, maxVal);
return Math.Max(left, right);
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: №16. 3Sum Closest
Сложность: medium
Учитывая целочисленный массив nums длины n и целочисленную цель, найдите три целых числа в nums, сумма которых наиболее близка к цели. Возвращает сумму трех целых чисел. Вы можете предположить, что каждый вход будет иметь ровно одно решение.
Пример:
Input: nums = [-1,2,1,-4], target = 1 Output: 2👨💻 Алгоритм: 1⃣Отсортировать массив и инициализировать переменные для отслеживания минимальной разницы. 2⃣Использовать два указателя (left и right) для поиска суммы трех чисел, обновляя их в зависимости от текущей суммы. 3⃣Возвращать сумму, которая наиболее близка к target. 😎 Решение:
public class Solution {
public int ThreeSumClosest(int[] nums, int target) {
Array.Sort(nums);
int closestSum = nums[0] + nums[1] + nums[2];
for (int i = 0; i < nums.Length - 2; i++) {
int left = i + 1, right = nums.Length - 1;
while (left < right) {
int currentSum = nums[i] + nums[left] + nums[right];
if (Math.Abs(target - currentSum) < Math.Abs(target - closestSum)) {
closestSum = currentSum;
}
if (currentSum < target) {
left++;
} else {
right--;
}
}
}
return closestSum;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
🚨60 минут
Пожизненный PRO-доступ на easyoffer (подготовка к IT-собесам + поиск оффера) по цене одного года закрывается прямо сейчас. Один платёж — доступ навсегда.
Последнее напоминание 👇
👉 https://easyoffer.ru/pro
3 194
⚠️ 3 часа до конца акции.
Последний шанс забрать пожизненный PRO на easyoffer по цене одного года. Это полный доступ к подготовке к собесам и инструментам поиска работы (вопросы с реальных интервью, ответы сеньоров, автоотклики, тренажёры) — один раз и навсегда, вместо ежегодной оплаты.
В полночь цена возвращается к обычной.
👉 https://easyoffer.ru/pro
3 194
⏳ Ребята, сегодня заканчивается акция, о которой стоит знать, если вы в поиске работы или планируете сменить её в ближайший год.
easyoffer — это платформа для подготовки к IT-собесам и поиска оффера. Внутри:
– база реальных вопросов и live-coding задач с собесов (с частотой их встречаемости)
– эталонные ответы от Senior-разработчиков
– 1100+ записей настоящих интервью (Сбер, Яндекс, Авито, WB, OZON, МТС)
– автоотклики на hh, генератор резюме под вакансию, тренажёры собеседований
Сегодня пожизненный PRO-доступ продаётся по цене одного года — платишь один раз и пользуешься всем этим всю жизнь, включая будущие фичи. С завтрашнего дня — только обычная годовая подписка.
👉 https://easyoffer.ru/pro
3 194
Задача: 233. Number of Digit One
Сложность: hard
Дано целое число n, посчитайте общее количество единиц, встречающихся во всех неотрицательных числах, меньших или равных n.
Пример:
Input: n = 13 Output: 6👨💻 Алгоритм: 1⃣Итерация по степеням 10: Итеративно увеличивайте значение i от 1 до n, увеличивая i в 10 раз на каждом шаге. Это позволяет анализировать каждую цифру числа n. 2⃣Подсчет групповых единиц: Для каждой итерации добавляйте (n / (i * 10)) * i к счетчику countr, что представляет собой количество единиц, встречающихся в группах размера i после каждого интервала (i * 10). 3⃣Добавление дополнительных единиц: Для каждой итерации добавляйте min(max((n % (i * 10)) - i + 1, 0), i) к счетчику countr, что представляет собой дополнительные единицы, зависящие от цифры на позиции i. 😎 Решение:
public class Solution {
public int CountDigitOne(int n) {
int countr = 0;
for (long i = 1; i <= n; i *= 10) {
long divider = i * 10;
countr += (n / divider) * i + Math.Min(Math.Max(n % divider - i + 1, 0), i);
}
return countr;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Пожизненный PRO — по цене одного года.
Покупаешь один раз — пользуешься всю жизнь:
👉 https://easyoffer.ru/pro
🚀 PRO-доступ закроет 99% проблем на пути к офферу:
1. 1100+ записей реальных собеседований (включая топы: Сбер, Авито, Яндекс, WB, OZON, МТС). Видите всё изнутри: как спрашивают, как отвечают сильные кандидаты и на каких ошибках проваливаются 80%.
2. База live-coding задач и вопросов с реальных собесов — с уникальной системой вероятности их встречи. Готовитесь не вслепую, а точечно по темам, которые спрашивают чаще всего.
3. Эталонные ответы от Senior-разработчиков. Никакой воды и догадок — только чёткие структурированные решения, за которые дают «зелёный свет» к офферу.
4. Полный доступ ко всем грейдам и профессиям. Junior вы или Senior, тестировщик, разработчик или проджект — вы получаете ВСЕ материалы easyoffer без ограничений. Безлимитно, Все, Навсегда.
5. База 400+ тестовых заданий. Прокачивайте навыки на реальных задачах — тех самых, что дают перед собесом.
6. Автоотклики на hh.ru — пока вы спите, резюме уходит рекрутерам автоматически. Экономия сотен часов ручного кликанья.
7. Аналитика ТОП-требований из вакансий. Парсим рынок и показываем, какие скиллы сейчас в цене. Апгрейдите резюме точечно и проходите ATS-фильтры (они отсеивают до 75% резюме ещё до рекрутера).
8. Генератор резюме и CV под каждую вакансию. Забудьте про «универсальное» резюме — нейросеть адаптирует ваш опыт под конкретную позицию за минуту и повышает шансы на приглашение в разы.
9. Тренажёры подготовки к собеседованию:
«Реальное собеседование» — сценарий вопросов из настоящих интервью. «Проработка вопросов» — флеш-карточки по методике интервальных повторений (как Anki)
10. 🔥 Самое важное: все будущие фичи
Вы платите один раз, а продукт растёт всю жизнь. Каждое обновление, каждый новый инструмент, каждая фича, которая появится за все годы проекта, автоматически падает вам в подписку без доплат. Вы фиксируете цену года, а получаете продукт, который через пару лет будет стоить в разы дороже
⭐️ Это уникальная акция пока сайт в режиме Beta.
Успей ей воспользоваться⏳ Завтра последний день.
👉 https://easyoffer.ru/pro
3 194
Задача: 665. Non-decreasing Array
Сложность: medium
Дан массив nums из n целых чисел. Ваша задача - проверить, можно ли сделать его неубывающим, изменив не более одного элемента.
Мы определяем массив как неубывающий, если для каждого i (индексация с 0), такого что 0 <= i <= n - 2, выполняется условие nums[i] <= nums[i + 1].
Пример:
Input: nums = [4,2,3] Output: true Explanation: You could modify the first 4 to 1 to get a non-decreasing array.👨💻 Алгоритм: 1⃣Инициализация переменных: Завести переменную count для подсчета числа изменений. Проверить последовательность чисел в массиве nums. 2⃣Проверка условий: Если nums[i] > nums[i + 1], то увеличиваем count. Если count превышает 1, возвращаем false, так как больше одного изменения недопустимо. Если nums[i - 1] > nums[i + 1] и nums[i] > nums[i + 2], то возвращаем false. 3⃣Возврат результата: Если количество изменений не превышает 1, вернуть true. 😎 Решение:
public class Solution {
public bool CheckPossibility(int[] nums) {
int count = 0;
for (int i = 1; i < nums.Length; i++) {
if (nums[i] < nums[i - 1]) {
if (count > 0) {
return false;
}
count++;
if (i == 1 || nums[i] >= nums[i - 2]) {
nums[i - 1] = nums[i];
} else {
nums[i] = nums[i - 1];
}
}
}
return true;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
🔥 Осталось 3 дня!
Пожизненный easyoffer PRO по цене одного года. Покупаешь один раз – пользуешься всю жизнь.
Что входит в PRO:
– Вопросы и задачи с реальных собеседований в конкретных компаниях
– Лучшие ответы и видео-примеры от middle/senior специалистов
– Записи реальных собеседований
– Обход фильтров ATS с топ-30 ключевых слов в резюме
– Автоотклики на hh
– Тренажёры и симуляторы для идеальной подготовки к интервью
⏳ Акция действует только до 2 сентября 23:59 по МСК
👉 Забрать PRO со скидкой 70%: https://easyoffer.ru/pro
3 194
Задача: 1493. Longest Subarray of 1's After Deleting One Element
Сложность: medium
Дан бинарный массив nums, из которого следует удалить один элемент.
Верните размер самой длинной непустой подмассивы, содержащей только 1, в результирующем массиве. Верните 0, если такого подмассива не существует.
Пример:
Input: nums = [0,1,1,1,0,1,1,0,1]
Output: 5
Explanation: After deleting the number in position 4, [0,1,1,1,1,1,0,1] longest subarray with value of 1's is [1,1,1,1,1].
👨💻 Алгоритм:
1⃣Инициализация переменных:
zeroCount для подсчёта нулей в текущем окне, longestWindow для хранения максимальной длины окна, содержащего не более одного нуля, и start для левой границы окна.
2⃣Итерация по массиву:
При каждом элементе увеличиваем zeroCount, если это ноль.
Если zeroCount превышает 1, сокращаем окно, перемещая левую границу вправо и уменьшая zeroCount, пока количество нулей не станет меньше или равно 1.
Обновляем longestWindow текущей длиной окна i - start.
3⃣ Возврат результата:
Вернуть longestWindow.
😎 Решение:
public class Solution {
public int LongestSubarray(int[] nums) {
int zeroCount = 0;
int longestWindow = 0;
int start = 0;
for (int i = 0; i < nums.Length; i++) {
if (nums[i] == 0) {
zeroCount++;
}
while (zeroCount > 1) {
if (nums[start] == 0) {
zeroCount--;
}
start++;
}
longestWindow = Math.Max(longestWindow, i - start);
}
return longestWindow;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 976. Largest Perimeter Triangle
Сложность: easy
Дан целочисленный массив nums. Верните наибольший периметр треугольника с ненулевой площадью, образованный из трех этих длин. Если невозможно образовать треугольник с ненулевой площадью, верните 0.
Пример:
Input: nums = [1,2,1,10] Output: 0 Explanation: You cannot use the side lengths 1, 1, and 2 to form a triangle. You cannot use the side lengths 1, 1, and 10 to form a triangle. You cannot use the side lengths 1, 2, and 10 to form a triangle. As we cannot use any three side lengths to form a triangle of non-zero area, we return 0.👨💻 Алгоритм: 1⃣Отсортируйте массив nums в порядке возрастания. 2⃣Для каждого элемента c в массиве, начиная с конца: Выберите два наибольших возможных значения a и b, которые находятся перед c в отсортированном массиве (т.е. значения, смежные с c). Проверьте, образуют ли a, b и c треугольник (условие треугольника: a + b > c). Если образуют, верните их сумму как периметр треугольника. 3⃣Если не удалось найти такие значения, верните 0. 😎 Решение:
public class Solution {
public int LargestPerimeter(int[] A) {
Array.Sort(A);
for (int i = A.Length - 3; i >= 0; --i)
if (A[i] + A[i + 1] > A[i + 2])
return A[i] + A[i + 1] + A[i + 2];
return 0;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 599. Minimum Index Sum of Two Lists
Сложность: easy
Даны два массива строк list1 и list2, необходимо найти общие строки с наименьшей суммой индексов.
Общая строка - это строка, которая появляется и в list1, и в list2.
Общая строка с наименьшей суммой индексов - это общая строка, такая, что если она появилась в list1[i] и list2[j], то i + j должно быть минимальным значением среди всех других общих строк.
Верните все общие строки с наименьшей суммой индексов. Верните ответ в любом порядке.
Пример:
Input: list1 = ["Shogun","Tapioca Express","Burger King","KFC"], list2 = ["Piatti","The Grill at Torrey Pines","Hungry Hunter Steakhouse","Shogun"] Output: ["Shogun"] Explanation: The only common string is "Shogun".👨💻 Алгоритм: 1⃣Для каждой строки из list1, сравниваем её с каждой строкой из list2, обходя весь список list2. Используем хэш-таблицу map, которая содержит элементы в виде (сумма: список строк). Здесь сумма относится к сумме индексов совпадающих элементов, а список строк соответствует списку совпадающих строк, чья сумма индексов равна этой сумме. 2⃣Во время сравнений, когда находится совпадение строки на i-м индексе из list1 и j-м индексе из list2, создаём запись в map, соответствующую сумме i + j, если такая запись ещё не существует. Если запись с этой суммой уже существует, добавляем текущую строку в список строк, соответствующих сумме i + j. 3⃣В конце обходим ключи в map и находим список строк, соответствующих ключу с минимальной суммой. 😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public string[] FindRestaurant(string[] list1, string[] list2) {
var map = new Dictionary<int, List<string>>();
for (int i = 0; i < list1.Length; i++) {
for (int j = 0; j < list2.Length; j++) {
if (list1[i] == list2[j]) {
if (!map.ContainsKey(i + j)) {
map[i + j] = new List<string>();
}
map[i + j].Add(list1[i]);
}
}
}
int minIndexSum = int.MaxValue;
foreach (var key in map.Keys) {
minIndexSum = Math.Min(minIndexSum, key);
}
return map[minIndexSum].ToArray();
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 811. Subdomain Visit Count
Сложность: medium
Веб-сайт с доменом "discuss.leetcode.com" состоит из различных поддоменов. На верхнем уровне у нас есть "com", на следующем уровне - "leetcode.com", и на самом нижнем уровне - "discuss.leetcode.com". Когда мы посещаем домен, такой как "discuss.leetcode.com", мы также автоматически посещаем родительские домены "leetcode.com" и "com".
Домен с парным счетчиком - это домен, который имеет один из двух форматов "rep d1.d2.d3" или "rep d1.d2", где rep - это количество посещений домена, а d1.d2.d3 - это сам домен.
Например, "9001 discuss.leetcode.com" - это домен с парным счетчиком, указывающий на то, что discuss.leetcode.com был посещен 9001 раз.
Дан массив доменов с парными счетчиками cpdomains, верните массив доменов с парными счетчиками для каждого поддомена во входных данных. Вы можете вернуть ответ в любом порядке.
Пример:
Input: cpdomains = ["9001 discuss.leetcode.com"] Output: ["9001 leetcode.com","9001 discuss.leetcode.com","9001 com"] Explanation: We only have one website domain: "discuss.leetcode.com". As discussed above, the subdomain "leetcode.com" and "com" will also be visited. So they will all be visited 9001 times.👨💻 Алгоритм: 1⃣Следуем указаниям из условия задачи. 2⃣Для адреса вида a.b.c, подсчитываем a.b.c, b.c и c. Для адреса вида x.y, подсчитываем x.y и y. 3⃣Для подсчета этих строк используем хеш-таблицу. Для разделения строк на требуемые части используем библиотечные функции split. 😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public IList<string> SubdomainVisits(string[] cpdomains) {
var ans = new Dictionary<string, int>();
foreach (var domain in cpdomains) {
var parts = domain.Split(' ');
var count = int.Parse(parts[0]);
var frags = parts[1].Split('.');
for (int i = 0; i < frags.Length; i++) {
var subdomain = string.Join(".", frags, i, frags.Length - i);
if (ans.ContainsKey(subdomain)) {
ans[subdomain] += count;
} else {
ans[subdomain] = count;
}
}
}
var res = new List<string>();
foreach (var entry in ans) {
res.Add($"{entry.Value} {entry.Key}");
}
return res;
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 1242. Web Crawler Multithreaded
Сложность: medium
Учитывая URL startUrl и интерфейс HtmlParser, реализуйте многопоточный веб-краулер, который будет просматривать все ссылки, находящиеся под тем же именем хоста, что и startUrl. Верните все URL, полученные вашим веб-краулером, в любом порядке.
Ваш краулер должен: Начинать со страницы: startUrl Вызывать HtmlParser.getUrls(url), чтобы получить все URL с веб-страницы данного URL. Не просматривать одну и ту же ссылку дважды. Исследовать только те ссылки, которые находятся под тем же именем хоста, что и startUrl.
Пример:
Input: urls = [ "http://news.yahoo.com", "http://news.yahoo.com/news", "http://news.yahoo.com/news/topics/", "http://news.google.com", "http://news.yahoo.com/us" ] edges = [[2,0],[2,1],[3,2],[3,1],[0,4]] startUrl = "http://news.yahoo.com/news/topics/" Output: [ "http://news.yahoo.com", "http://news.yahoo.com/news", "http://news.yahoo.com/news/topics/", "http://news.yahoo.com/us" ]👨💻 Алгоритм: 1⃣Извлечь имя хоста из startUrl. Использовать многопоточность для обработки URL-адресов. 2⃣Хранить посещенные URL-адреса, чтобы избежать повторного посещения. 3⃣Использовать HtmlParser для получения URL-адресов с веб-страниц. 😎 Решение:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
public class HtmlParser {
public List<string> GetUrls(string url) {
return new List<string>();
}
}
public class Solution {
private ConcurrentDictionary<string, bool> visited = new ConcurrentDictionary<string, bool>();
private string hostname;
private HtmlParser htmlParser;
public IList<string> Crawl(string startUrl, HtmlParser htmlParser) {
this.hostname = new Uri(startUrl).Host;
this.htmlParser = htmlParser;
var tasks = new List<Task>();
visited.TryAdd(startUrl, true);
tasks.Add(Task.Run(() => Visit(startUrl)));
Task.WaitAll(tasks.ToArray());
return visited.Keys.ToList();
}
private async Task Visit(string url) {
foreach (var nextUrl in htmlParser.GetUrls(url)) {
if (new Uri(nextUrl).Host == hostname && visited.TryAdd(nextUrl, true)) {
await Visit(nextUrl);
}
}
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 347. Top K Frequent Elements
Сложность: medium
Дан массив целых чисел nums и целое число k. Верните k самых частых элементов. Вы можете вернуть ответ в любом порядке.
Пример:
Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2]👨💻 Алгоритм: 1⃣Подсчет частоты: Используйте хеш-таблицу или словарь для подсчета количества вхождений каждого элемента в массиве nums. 2⃣Создание кучи: Создайте кучу, чтобы отсортировать элементы по их частоте и выбрать k самых частых элементов. 3⃣Возврат результата: Верните k самых частых элементов. 😎 Решение:
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int[] TopKFrequent(int[] nums, int k) {
var count = nums.GroupBy(n => n)
.ToDictionary(g => g.Key, g => g.Count());
return count.OrderByDescending(x => x.Value)
.Take(k)
.Select(x => x.Key)
.ToArray();
}
}
Ставь 👍 и забирай 📚 Базу знаний3 194
Задача: 1485. Clone Binary Tree With Random Pointer
Сложность: medium
Дано бинарное дерево, такое что каждый узел содержит дополнительный случайный указатель, который может указывать на любой узел в дереве или быть null.
Верните глубокую копию дерева.
Дерево представлено в том же формате ввода/вывода, что и обычные бинарные деревья, где каждый узел представлен в виде пары [val, random_index], где:
- val: целое число, представляющее Node.val
- random_index: индекс узла (во входных данных), на который указывает случайный указатель, или null, если он не указывает ни на один узел.
Вам будет дано дерево в классе Node, и вы должны вернуть клонированное дерево в классе NodeCopy. Класс NodeCopy является клоном класса Node с такими же атрибутами и конструкторами.
Пример:
Input: root = [[1,null],null,[4,3],[7,0]]
Output: [[1,null],null,[4,3],[7,0]]
Explanation: The original binary tree is [1,null,4,7].
The random pointer of node one is null, so it is represented as [1, null].
The random pointer of node 4 is node 7, so it is represented as [4, 3] where 3 is the index of node 7 in the array representing the tree.
The random pointer of node 7 is node 1, so it is represented as [7, 0] where 0 is the index of node 1 in the array representing the tree.
👨💻 Алгоритм:
1⃣Глубокое копирование дерева:
Инициализируйте хэш-таблицу newOldPairs, которая сопоставляет узлы старого дерева с узлами нового дерева.
Создайте функцию deepCopy(root), которая принимает корень данного дерева и возвращает корень нового дерева. Эта функция создаёт новый узел с теми же значениями, что и корневой узел, и рекурсивно копирует левое и правое поддеревья. Затем она сохраняет пару старого и нового узлов в хэш-таблицу и возвращает новый корень.
2⃣Сопоставление случайных указателей:
Создайте функцию mapRandomPointers(oldNode), которая принимает корень старого дерева и рекурсивно сопоставляет случайные указатели нового дерева с соответствующими узлами старого дерева, используя хэш-таблицу newOldPairs.
3⃣Возвращение клонированного дерева:
Создайте глубокую копию дерева, используя функцию deepCopy(root), и сопоставьте все случайные указатели нового дерева с помощью функции mapRandomPointers(root). Верните новый корень.
😎 Решение:
public class Node {
public int val;
public Node left;
public Node right;
public Node random;
public Node(int _val) {
val = _val;
left = null;
right = null;
random = null;
}
}
public class NodeCopy {
public int val;
public NodeCopy left;
public NodeCopy right;
public NodeCopy random;
public NodeCopy(int _val) {
val = _val;
left = null;
right = null;
random = null;
}
}
public class Solution {
private Dictionary<Node, NodeCopy> newOldPairs = new Dictionary<Node, NodeCopy>();
private NodeCopy DeepCopy(Node root) {
if (root == null) return null;
NodeCopy newRoot = new NodeCopy(root.val);
newRoot.left = DeepCopy(root.left);
newRoot.right = DeepCopy(root.right);
newOldPairs[root] = newRoot;
return newRoot;
}
private void MapRandomPointers(Node oldNode) {
if (oldNode == null) return;
if (newOldPairs.TryGetValue(oldNode, out NodeCopy newNode)) {
newNode.random = newOldPairs.GetValueOrDefault(oldNode.random);
MapRandomPointers(oldNode.left);
MapRandomPointers(oldNode.right);
}
}
public NodeCopy CopyRandomBinaryTree(Node root) {
NodeCopy newRoot = DeepCopy(root);
MapRandomPointers(root);
return newRoot;
}
}
Ставь 👍 и забирай 📚 Базу знаний