Задача: 686. Repeated String Match
Сложность: medium
Даны две строки a и b. Верните минимальное количество повторений строки a, чтобы строка b стала её подстрокой. Если сделать b подстрокой a невозможно, верните -1.
Обратите внимание: строка "abc", повторенная 0 раз, это "", повторенная 1 раз - "abc", повторенная 2 раза - "abcabc".
Пример:
👨💻 Алгоритм:
1⃣ Найти минимальное количество повторений строки A, чтобы её длина стала больше или равна длине B. Это значение q = ceil(len(B) / len(A)).
2⃣ Проверить, является ли B подстрокой строки A, повторенной q раз. Если да, вернуть q. Иначе, проверить строку A, повторенную (q+1) раз. Если B является подстрокой этой строки, вернуть q+1.
3⃣ Если B не является подстрокой ни в одном из случаев, вернуть -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны две строки a и b. Верните минимальное количество повторений строки a, чтобы строка b стала её подстрокой. Если сделать b подстрокой a невозможно, верните -1.
Обратите внимание: строка "abc", повторенная 0 раз, это "", повторенная 1 раз - "abc", повторенная 2 раза - "abcabc".
Пример:
Input: a = "abcd", b = "cdabcdab"
Output: 3
Explanation: We return 3 because by repeating a three times "abcdabcdabcd", b is a substring of it.
class Solution {
public int repeatedStringMatch(String A, String B) {
int q = 1;
StringBuilder S = new StringBuilder(A);
while (S.length() < B.length()) {
S.append(A);
q++;
}
if (S.indexOf(B) >= 0) return q;
if (S.append(A).indexOf(B) >= 0) return q + 1;
return -1;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 943. Find the Shortest Superstring
Сложность: hard
Учитывая массив строк words, верните наименьшую строку, которая содержит каждую строку в words в качестве подстроки. Если существует несколько допустимых строк наименьшей длины, верните любую из них. Вы можете предположить, что ни одна строка в words не является подстрокой другой строки в words.
Пример:
👨💻 Алгоритм:
1⃣ Реализовать функцию overlap для вычисления максимального перекрытия двух строк, где одна строка заканчивается, а другая начинается.
2⃣ Реализовать функцию merge для объединения двух строк с максимальным перекрытием.
Использовать жадный алгоритм для нахождения двух строк с максимальным перекрытием и объединить их, повторяя до тех пор, пока не останется одна строка.
3⃣ Вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Учитывая массив строк words, верните наименьшую строку, которая содержит каждую строку в words в качестве подстроки. Если существует несколько допустимых строк наименьшей длины, верните любую из них. Вы можете предположить, что ни одна строка в words не является подстрокой другой строки в words.
Пример:
Input: words = ["alex","loves","leetcode"]
Output: "alexlovesleetcode"
Использовать жадный алгоритм для нахождения двух строк с максимальным перекрытием и объединить их, повторяя до тех пор, пока не останется одна строка.
import java.util.ArrayList;
import java.util.List;
class Solution {
public String shortestSuperstring(String[] words) {
int n = words.length;
while (n > 1) {
int maxOverlap = -1, l = 0, r = 0;
String merged = "";
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i != j) {
int overlapLen = overlap(words[i], words[j]);
if (overlapLen > maxOverlap) {
maxOverlap = overlapLen;
l = i;
r = j;
merged = merge(words[i], words[j], overlapLen);
}
}
}
}
words[l] = merged;
words[r] = words[n - 1];
n--;
}
return words[0];
}
private int overlap(String a, String b) {
int maxOverlap = 0;
for (int i = 1; i <= Math.min(a.length(), b.length()); i++) {
if (a.substring(a.length() - i).equals(b.substring(0, i))) {
maxOverlap = i;
}
}
return maxOverlap;
}
private String merge(String a, String b, int overlapLen) {
return a + b.substring(overlapLen);
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 970. Powerful Integers
Сложность: medium
Даны три целых числа x, y и bound. Верните список всех мощных чисел, которые имеют значение меньше или равное bound.
Целое число является мощным, если оно может быть представлено как x^i + y^j для некоторых целых чисел i >= 0 и j >= 0.
Вы можете вернуть ответ в любом порядке. В вашем ответе каждое значение должно встречаться не более одного раза.
Пример:
👨💻 Алгоритм:
1⃣ Вычислите степени a и b как логарифмы bound по основаниям x и y соответственно. Создайте множество powerfulIntegers для хранения результатов.
2⃣ Используйте вложенные циклы, где внешний цикл проходит от 0 до a, а внутренний цикл от 0 до b. На каждом шаге вычисляйте x^i + y^j и, если значение меньше или равно bound, добавляйте его в множество powerfulIntegers.
3⃣ Используйте вложенные циклы, где внешний цикл проходит от 0 до a, а внутренний цикл от 0 до b. На каждом шаге вычисляйте x^i + y^j и, если значение меньше или равно bound, добавляйте его в множество powerfulIntegers.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны три целых числа x, y и bound. Верните список всех мощных чисел, которые имеют значение меньше или равное bound.
Целое число является мощным, если оно может быть представлено как x^i + y^j для некоторых целых чисел i >= 0 и j >= 0.
Вы можете вернуть ответ в любом порядке. В вашем ответе каждое значение должно встречаться не более одного раза.
Пример:
Input: x = 2, y = 3, bound = 10
Output: [2,3,4,5,7,9,10]
Explanation:
2 = 20 + 30
3 = 21 + 30
4 = 20 + 31
5 = 21 + 31
7 = 22 + 31
9 = 23 + 30
10 = 20 + 32
class Solution {
public List<Integer> powerfulIntegers(int x, int y, int bound) {
int a = x == 1 ? bound : (int) (Math.log(bound) / Math.log(x));
int b = y == 1 ? bound : (int) (Math.log(bound) / Math.log(y));
HashSet<Integer> powerfulIntegers = new HashSet<Integer>();
for (int i = 0; i <= a; i++) {
for (int j = 0; j <= b; j++) {
int value = (int) Math.pow(x, i) + (int) Math.pow(y, j);
if (value <= bound) {
powerfulIntegers.add(value);
}
if (y == 1) {
break;
}
}
if (x == 1) {
break;
}
}
return new ArrayList<Integer>(powerfulIntegers);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
🎉 Easyoffer 2.0 — самый успешный краудфандинг в истории рунета в категории "Технологии"!
Мы это сделали! За считанные часы после старта, благодаря вашей поддержке, проект не просто стартовал — он взлетел.
💸 Собрано: 2 276 840 рублей
Это не просто цифра — это ваше доверие, ваша вера в идею, и ваша инвестиция в будущее карьеры сотен (а скоро — тысяч) специалистов.
💼 Благодаря этой сумме мы уже:
— Наняли ещё пару разработчиков и аналитиков
— Запустили активный сбор и разметку новых данных
— Ускорили разработку и подняли планку качества
Спасибо каждому, кто поверил в нас на старте! Дальше — только масштабирование и развитие. Мы строим сервис, который станет must-have для всех, кто ищет работу в IT.
👉 Присоединяйтесь сейчас — это только начало.
Мы это сделали! За считанные часы после старта, благодаря вашей поддержке, проект не просто стартовал — он взлетел.
💸 Собрано: 2 276 840 рублей
Это не просто цифра — это ваше доверие, ваша вера в идею, и ваша инвестиция в будущее карьеры сотен (а скоро — тысяч) специалистов.
💼 Благодаря этой сумме мы уже:
— Наняли ещё пару разработчиков и аналитиков
— Запустили активный сбор и разметку новых данных
— Ускорили разработку и подняли планку качества
Спасибо каждому, кто поверил в нас на старте! Дальше — только масштабирование и развитие. Мы строим сервис, который станет must-have для всех, кто ищет работу в IT.
👉 Присоединяйтесь сейчас — это только начало.
💊1
Задача: 345. Reverse Vowels of a String
Сложность: easy
Дана строка s, переверните только все гласные в строке и верните её.
Гласные: 'a', 'e', 'i', 'o', 'u', а также их верхние регистры.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация указателей и гласных:
Создайте набор гласных для быстрой проверки.
Установите два указателя: один на начало строки (left), другой на конец строки (right).
2⃣ Перестановка гласных:
Пока левый указатель меньше правого, перемещайте указатели к центру, пока не найдёте гласные.
Обменивайте найденные гласные и продолжайте сдвигать указатели.
3⃣ Завершение работы:
Когда указатели пересекутся, остановите процесс и верните строку.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дана строка s, переверните только все гласные в строке и верните её.
Гласные: 'a', 'e', 'i', 'o', 'u', а также их верхние регистры.
Пример:
Input: s = "hello"
Output: "holle"
Создайте набор гласных для быстрой проверки.
Установите два указателя: один на начало строки (left), другой на конец строки (right).
Пока левый указатель меньше правого, перемещайте указатели к центру, пока не найдёте гласные.
Обменивайте найденные гласные и продолжайте сдвигать указатели.
Когда указатели пересекутся, остановите процесс и верните строку.
public class Solution {
public String reverseVowels(String s) {
Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
char[] chars = s.toCharArray();
int left = 0, right = s.length() - 1;
while (left < right) {
if (!vowels.contains(chars[left])) {
left++;
} else if (!vowels.contains(chars[right])) {
right--;
} else {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
return new String(chars);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Задача: 1372. Longest ZigZag Path in a Binary Tree
Сложность: medium
Вам дан корень бинарного дерева.
Зигзагообразный путь для бинарного дерева определяется следующим образом:
Выберите любой узел в бинарном дереве и направление (вправо или влево).
Если текущее направление вправо, перейдите к правому дочернему узлу текущего узла; иначе перейдите к левому дочернему узлу.
Измените направление с вправо на влево или с влево на вправо.
Повторяйте второй и третий шаги, пока не сможете двигаться по дереву.
Длина зигзагообразного пути определяется как количество посещенных узлов минус 1 (один узел имеет длину 0).
Верните длину самого длинного зигзагообразного пути, содержащегося в этом дереве.
Пример:
👨💻 Алгоритм:
1⃣ Рекурсивная функция DFS:
Создайте рекурсивную функцию dfs, которая будет выполнять обход дерева и отслеживать текущую длину зигзагообразного пути и направление движения (влево или вправо).
2⃣ Обновление максимальной длины пути:
При каждом вызове рекурсивной функции обновляйте максимальную длину зигзагообразного пути, если текущая длина больше текущего максимума.
3⃣ Рекурсивный вызов для левого и правого дочерних узлов:
Рекурсивно вызывайте функцию dfs для левого и правого дочерних узлов с обновленными параметрами длины и направления.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан корень бинарного дерева.
Зигзагообразный путь для бинарного дерева определяется следующим образом:
Выберите любой узел в бинарном дереве и направление (вправо или влево).
Если текущее направление вправо, перейдите к правому дочернему узлу текущего узла; иначе перейдите к левому дочернему узлу.
Измените направление с вправо на влево или с влево на вправо.
Повторяйте второй и третий шаги, пока не сможете двигаться по дереву.
Длина зигзагообразного пути определяется как количество посещенных узлов минус 1 (один узел имеет длину 0).
Верните длину самого длинного зигзагообразного пути, содержащегося в этом дереве.
Пример:
Input: s = "rat"
Output: "art"
Explanation: The word "rat" becomes "art" after re-ordering it with the mentioned algorithm.
Создайте рекурсивную функцию dfs, которая будет выполнять обход дерева и отслеживать текущую длину зигзагообразного пути и направление движения (влево или вправо).
При каждом вызове рекурсивной функции обновляйте максимальную длину зигзагообразного пути, если текущая длина больше текущего максимума.
Рекурсивно вызывайте функцию dfs для левого и правого дочерних узлов с обновленными параметрами длины и направления.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
private int maxLength = 0;
public int longestZigZag(TreeNode root) {
dfs(root, true, 0);
dfs(root, false, 0);
return maxLength;
}
private void dfs(TreeNode node, boolean isLeft, int length) {
if (node == null) {
return;
}
maxLength = Math.max(maxLength, length);
if (isLeft) {
dfs(node.left, false, length + 1);
dfs(node.right, true, 1);
} else {
dfs(node.right, true, length + 1);
dfs(node.left, false, 1);
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1119. Remove Vowels from a String
Сложность: easy
Дана строка s, удалите из нее гласные 'a', 'e', 'i', 'o' и 'u' и верните новую строку.
Пример:
👨💻 Алгоритм:
1⃣ Создайте метод isVowel(), который возвращает true, если переданный символ является одной из гласных [a, e, i, o, u], и false в противном случае.
2⃣ Инициализируйте пустую строку ans.
3⃣ Пройдитесь по каждому символу в строке s, и для каждого символа c проверьте, является ли он гласной, используя isVowel(c). Если нет, добавьте символ в строку ans. В конце верните строку ans.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дана строка s, удалите из нее гласные 'a', 'e', 'i', 'o' и 'u' и верните новую строку.
Пример:
Input: s = "leetcodeisacommunityforcoders"
Output: "ltcdscmmntyfrcdrs"
class Solution {
private boolean isVowel(char c) {
return c == 'a' || c == 'i' || c == 'e' || c == 'o' || c == 'u';
}
public String removeVowels(String s) {
StringBuffer ans = new StringBuffer(s.length());
for (int i = 0; i < s.length(); i++) {
if (!isVowel(s.charAt(i))) {
ans.append(s.charAt(i));
}
}
return ans.toString();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Что такое PRO-подписка на easyoffer 2.0?
easyoffer PRO — это не просто доступ к базе, а полноценный инструмент для получения оффера.
🧠 База вопросов с собеседований
+ Анализ на основе 4,000 собеседований
+ Вероятность встречи каждого вопроса
+ Фильтрация по грейдам, компаниям, типам интервью
+ Примеры ответов: текстовые и видео
+ Готовьтесь к собеседованию в конкретную компанию
🛠 Тренажер "Проработка вопросов"
+ Флеш-карточки + интервальные повторения
+ Персональная система показа карточек в зависимости от ваших ответов
+ Упор на наиболее частые вопросы
+ Фокус на слабые места и быстрый прогресс
🎭 Тренажер "Реальное собеседование"
+ Сценарии на основе реальных интервью
+ Подготовка к конкретным компаниям
+ Итоговая статистика: прошёл/не прошёл
🧩 База задач с собеседований
+ Live-coding и System Design задачи
+ Оценка вероятности встречи задачи
+ Подготовка к задачам по конкретным компаниям
📋 База тестовых заданий
+ Задания из реальных вакансий
+ Фильтрация по технологиям и грейдам
+ Лучшие решения в доступе
📈 Тренды технологий в вакансиях
+ Топ-100 навыков, которые требуют компании
+ Динамика популярности технологий
+ Фильтрация по грейдам
🎁 Специальная цена до релиза:
3200 руб. за целый год
Сейчас PRO на 1 год стоит как будет стоить 1 месяц после релиза. Покупка также открывает доступ к закрытому бета-тестированию.
+ Вы можете активировать подписку в любой момент, например, когда начнете искать работу.
Предзаказ здесь: https://planeta.ru/campaigns/easyoffer
📌 Цена поднимется сразу после запуска.
Если вы хотите перестать угадывать, что спросят на собеседовании, и начать точечно готовиться на основе реальных данных — easyoffer PRO именно для вас.
Экономьте время. Получайте оффер легко.
easyoffer PRO — это не просто доступ к базе, а полноценный инструмент для получения оффера.
🧠 База вопросов с собеседований
+ Анализ на основе 4,000 собеседований
+ Вероятность встречи каждого вопроса
+ Фильтрация по грейдам, компаниям, типам интервью
+ Примеры ответов: текстовые и видео
+ Готовьтесь к собеседованию в конкретную компанию
🛠 Тренажер "Проработка вопросов"
+ Флеш-карточки + интервальные повторения
+ Персональная система показа карточек в зависимости от ваших ответов
+ Упор на наиболее частые вопросы
+ Фокус на слабые места и быстрый прогресс
🎭 Тренажер "Реальное собеседование"
+ Сценарии на основе реальных интервью
+ Подготовка к конкретным компаниям
+ Итоговая статистика: прошёл/не прошёл
🧩 База задач с собеседований
+ Live-coding и System Design задачи
+ Оценка вероятности встречи задачи
+ Подготовка к задачам по конкретным компаниям
📋 База тестовых заданий
+ Задания из реальных вакансий
+ Фильтрация по технологиям и грейдам
+ Лучшие решения в доступе
📈 Тренды технологий в вакансиях
+ Топ-100 навыков, которые требуют компании
+ Динамика популярности технологий
+ Фильтрация по грейдам
🎁 Специальная цена до релиза:
3200 руб. за целый год
Сейчас PRO на 1 год стоит как будет стоить 1 месяц после релиза. Покупка также открывает доступ к закрытому бета-тестированию.
+ Вы можете активировать подписку в любой момент, например, когда начнете искать работу.
Предзаказ здесь: https://planeta.ru/campaigns/easyoffer
📌 Цена поднимется сразу после запуска.
Если вы хотите перестать угадывать, что спросят на собеседовании, и начать точечно готовиться на основе реальных данных — easyoffer PRO именно для вас.
Экономьте время. Получайте оффер легко.
Задача: 826. Most Profit Assigning Work
Сложность: medium
У вас есть n заданий и m рабочих. Вам даны три массива: difficulty, profit и worker, где:
difficulty[i] и profit[i] — сложность и прибыль i-го задания,
worker[j] — способность j-го рабочего (т.е. j-й рабочий может выполнить задание со сложностью не больше worker[j]).
Каждому рабочему можно назначить не более одного задания, но одно задание может быть выполнено несколько раз.
Например, если три рабочих выполняют одно и то же задание с оплатой $1, общая прибыль составит $3. Если рабочий не может выполнить ни одно задание, его прибыль равна $0.
Верните максимальную прибыль, которую можно получить после распределения рабочих по заданиям.
Пример:
👨💻 Алгоритм:
1⃣ Создание и сортировка профиля работы
Инициализируйте массив пар jobProfile с {0, 0}. Для каждого задания добавьте {difficulty[i], profit[i]} в jobProfile. Отсортируйте jobProfile по возрастанию сложности.
2⃣ Обновление максимальной прибыли для каждой сложности
Обновите значение прибыли каждой сложности, чтобы оно было максимальным из текущего значения и предыдущего значения прибыли.
3⃣ Вычисление максимальной прибыли
Для каждой способности рабочего используйте бинарный поиск, чтобы найти задание с наибольшей прибылью, которую может выполнить этот рабочий. Суммируйте полученную прибыль для всех рабочих и верните ее.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
У вас есть n заданий и m рабочих. Вам даны три массива: difficulty, profit и worker, где:
difficulty[i] и profit[i] — сложность и прибыль i-го задания,
worker[j] — способность j-го рабочего (т.е. j-й рабочий может выполнить задание со сложностью не больше worker[j]).
Каждому рабочему можно назначить не более одного задания, но одно задание может быть выполнено несколько раз.
Например, если три рабочих выполняют одно и то же задание с оплатой $1, общая прибыль составит $3. Если рабочий не может выполнить ни одно задание, его прибыль равна $0.
Верните максимальную прибыль, которую можно получить после распределения рабочих по заданиям.
Пример:
Input: difficulty = [2,4,6,8,10], profit = [10,20,30,40,50], worker = [4,5,6,7]
Output: 100
Explanation: Workers are assigned jobs of difficulty [4,4,6,6] and they get a profit of [20,20,30,30] separately.
Инициализируйте массив пар jobProfile с {0, 0}. Для каждого задания добавьте {difficulty[i], profit[i]} в jobProfile. Отсортируйте jobProfile по возрастанию сложности.
Обновите значение прибыли каждой сложности, чтобы оно было максимальным из текущего значения и предыдущего значения прибыли.
Для каждой способности рабочего используйте бинарный поиск, чтобы найти задание с наибольшей прибылью, которую может выполнить этот рабочий. Суммируйте полученную прибыль для всех рабочих и верните ее.
class Solution {
public int maxProfitAssignment(
int[] difficulty,
int[] profit,
int[] worker
) {
List<int[]> jobProfile = new ArrayList<>();
jobProfile.add(new int[] { 0, 0 });
for (int i = 0; i < difficulty.length; i++) {
jobProfile.add(new int[] { difficulty[i], profit[i] });
}
Collections.sort(jobProfile, (a, b) -> Integer.compare(a[0], b[0]));
for (int i = 0; i < jobProfile.size() - 1; i++) {
jobProfile.get(i + 1)[1] = Math.max(
jobProfile.get(i)[1],
jobProfile.get(i + 1)[1]
);
}
int netProfit = 0;
for (int i = 0; i < worker.length; i++) {
int ability = worker[i];
int l = 0, r = jobProfile.size() - 1, jobProfit = 0;
while (l <= r) {
int mid = (l + r) / 2;
if (jobProfile.get(mid)[0] <= ability) {
jobProfit = Math.max(jobProfit, jobProfile.get(mid)[1]);
l = mid + 1;
} else {
r = mid - 1;
}
}
netProfit += jobProfit;
}
return netProfit;
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1017. Convert to Base -2
Сложность: medium
Если задано целое число n, верните двоичную строку, представляющую его в базе -2. Обратите внимание, что возвращаемая строка не должна содержать ведущих нулей, за исключением случаев, когда строка равна "0".
Пример:
👨💻 Алгоритм:
1⃣ Инициализация переменных:
Создайте пустую строку для хранения двоичного представления числа.
Используйте цикл для вычисления каждой цифры числа в базе -2.
2⃣ Вычисление цифр:
В цикле, пока число не равно 0, вычисляйте остаток от деления числа на -2.
Если остаток отрицательный, корректируйте его, добавляя 2, и увеличивайте число на 1.
Добавляйте остаток в начало строки.
3⃣ Возврат результата:
Верните строку, представляющую число в базе -2. Если строка пустая, верните "0".
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задано целое число n, верните двоичную строку, представляющую его в базе -2. Обратите внимание, что возвращаемая строка не должна содержать ведущих нулей, за исключением случаев, когда строка равна "0".
Пример:
Input: n = 2
Output: "110"
Создайте пустую строку для хранения двоичного представления числа.
Используйте цикл для вычисления каждой цифры числа в базе -2.
В цикле, пока число не равно 0, вычисляйте остаток от деления числа на -2.
Если остаток отрицательный, корректируйте его, добавляя 2, и увеличивайте число на 1.
Добавляйте остаток в начало строки.
Верните строку, представляющую число в базе -2. Если строка пустая, верните "0".
public class Solution {
public String baseNeg2(int n) {
if (n == 0) return "0";
StringBuilder res = new StringBuilder();
while (n != 0) {
int remainder = n % -2;
n /= -2;
if (remainder < 0) {
remainder += 2;
n += 1;
}
res.insert(0, remainder);
}
return res.toString();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 969. Pancake Sorting
Сложность: medium
Дан массив целых чисел arr, отсортируйте массив, выполняя серию переворотов блинов.
При одном перевороте блина мы выполняем следующие шаги:
Выбираем целое число k, где 1 <= k <= arr.length.
Переворачиваем подмассив arr[0...k-1] (индексация с 0).
Например, если arr = [3,2,1,4] и мы выполнили переворот блина, выбрав k = 3, мы переворачиваем подмассив [3,2,1], так что arr = [1,2,3,4] после переворота блина при k = 3.
Верните массив значений k, соответствующих последовательности переворотов блинов, которая сортирует arr. Любой допустимый ответ, который сортирует массив за количество переворотов не более чем 10 * arr.length, будет считаться правильным.
Пример:
👨💻 Алгоритм:
1⃣ Вдохновляясь пузырьковой сортировкой, начнем с реализации функции flip(list, k), которая выполняет переворот блина на префиксе list[0
] (в Python).
2⃣ Основной алгоритм выполняет цикл по значениям списка, начиная с наибольшего.
3⃣ На каждом этапе определяем значение для сортировки (назовем его value_to_sort), которое является числом, которое мы будем ставить на место на этом этапе. Затем находим индекс value_to_sort. Если value_to_sort еще не на своем месте, выполняем максимум два переворота блинов, как объяснено в интуиции. В конце этапа value_to_sort будет на своем месте.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел arr, отсортируйте массив, выполняя серию переворотов блинов.
При одном перевороте блина мы выполняем следующие шаги:
Выбираем целое число k, где 1 <= k <= arr.length.
Переворачиваем подмассив arr[0...k-1] (индексация с 0).
Например, если arr = [3,2,1,4] и мы выполнили переворот блина, выбрав k = 3, мы переворачиваем подмассив [3,2,1], так что arr = [1,2,3,4] после переворота блина при k = 3.
Верните массив значений k, соответствующих последовательности переворотов блинов, которая сортирует arr. Любой допустимый ответ, который сортирует массив за количество переворотов не более чем 10 * arr.length, будет считаться правильным.
Пример:
Input: arr = [3,2,4,1]
Output: [4,2,4,3]
Explanation:
We perform 4 pancake flips, with k values 4, 2, 4, and 3.
Starting state: arr = [3, 2, 4, 1]
After 1st flip (k = 4): arr = [1, 4, 2, 3]
After 2nd flip (k = 2): arr = [4, 1, 2, 3]
After 3rd flip (k = 4): arr = [3, 2, 1, 4]
After 4th flip (k = 3): arr = [1, 2, 3, 4], which is sorted.
] (в Python).
class Solution {
public List<Integer> pancakeSort(int[] A) {
List<Integer> ans = new ArrayList<>();
for (int valueToSort = A.length; valueToSort > 0; valueToSort--) {
int index = find(A, valueToSort);
if (index == valueToSort - 1) continue;
if (index != 0) {
ans.add(index + 1);
flip(A, index + 1);
}
ans.add(valueToSort);
flip(A, valueToSort);
}
return ans;
}
protected void flip(int[] sublist, int k) {
int i = 0;
while (i < k / 2) {
int temp = sublist[i];
sublist[i] = sublist[k - i - 1];
sublist[k - i - 1] = temp;
i++;
}
}
protected int find(int[] a, int target) {
for (int i = 0; i < a.length; i++) {
if (a[i] == target) {
return i;
}
}
return -1;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Задача: 1214. Two Sum BSTs
Сложность: medium
Даны корни двух бинарных деревьев поиска, root1 и root2, верните true, если и только если существует узел в первом дереве и узел во втором дереве, значения которых в сумме равны заданному целому числу target.
Пример:
👨💻 Алгоритм:
1⃣ Создайте два пустых множества node_set1 и node_set2. Выполните обход дерева root1, добавляя значения каждого узла в node_set1, и выполните обход дерева root2, добавляя значения каждого узла в node_set2.
2⃣ Итерация по элементам в node_set1: для каждого элемента value1 проверяйте, находится ли target - value1 в node_set2.
3⃣ Если target - value1 находится в node_set2, верните true. Если после завершения итерации не найдено ни одной подходящей пары, верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны корни двух бинарных деревьев поиска, root1 и root2, верните true, если и только если существует узел в первом дереве и узел во втором дереве, значения которых в сумме равны заданному целому числу target.
Пример:
Input: root1 = [0,-10,10], root2 = [5,1,7,0,2], target = 18
Output: false
class Solution {
private void dfs(TreeNode currNode, Set<Integer> nodeSet) {
if (currNode == null) {
return;
}
dfs(currNode.left, nodeSet);
nodeSet.add(currNode.val);
dfs(currNode.right, nodeSet);
}
public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) {
Set<Integer> nodeSet1 = new HashSet<>();
Set<Integer> nodeSet2 = new HashSet<>();
dfs(root1, nodeSet1);
dfs(root2, nodeSet2);
for (int value1 : nodeSet1) {
if (nodeSet2.contains(target - value1)) {
return true;
}
}
return false;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Задача: 1802. Maximum Value at a Given Index in a Bounded Array
Сложность: medium
Даны три положительных целых числа:
-
-
-
- Сумма всех элементов массива
-
Верните значение
Обратите внимание, что
Пример:
👨💻 Алгоритм:
1⃣ Определите функцию getSum(index, value) для вычисления минимальной суммы массива при условии, что nums[index] = value.
2⃣ Инициализируйте диапазон поиска [left, right] значениями left = 1 и right = maxSum. Выполните бинарный поиск: вычислите mid = (left + right + 1) / 2 и проверьте, если getSum(index, mid) <= maxSum. Если условие выполняется, установите left = mid, иначе установите right = mid - 1.
3⃣ Верните left по завершении бинарного поиска.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны три положительных целых числа:
n, index и maxSum. Вам нужно построить массив nums (индексация с нуля), который удовлетворяет следующим условиям:-
nums.length == n-
nums[i] является положительным целым числом, где 0 <= i < n.-
abs(nums[i] - nums[i+1]) <= 1, где 0 <= i < n-1.- Сумма всех элементов массива
nums не превышает maxSum.-
nums[index] максимально возможен.Верните значение
nums[index] в построенном массиве.Обратите внимание, что
abs(x) равно x, если x >= 0, и -x в противном случае.Пример:
Input: n = 4, index = 2, maxSum = 6
Output: 2
class Solution {
private long getSum(int index, int value, int n) {
long count = 0;
if (value > index) {
count += (long)(value + value - index) * (index + 1) / 2;
} else {
count += (long)(value + 1) * value / 2 + index - value + 1;
}
if (value >= n - index) {
count += (long)(value + value - n + 1 + index) * (n - index) / 2;
} else {
count += (long)(value + 1) * value / 2 + n - index - value;
}
return count - value;
}
public int maxValue(int n, int index, int maxSum) {
int left = 1, right = maxSum;
while (left < right) {
int mid = (left + right + 1) / 2;
if (getSum(index, mid, n) <= maxSum) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1250. Check If It Is a Good Array
Сложность: hard
Дан массив nums из целых положительных чисел. Ваша задача - выбрать некоторое подмножество nums, умножить каждый элемент на целое число и сложить все эти числа.Массив считается хорошим, если из него можно получить сумму, равную 1, при любом возможном подмножестве и множителе. Верните True, если массив хороший, иначе верните False.
Пример:
👨💻 Алгоритм:
1⃣ Если наибольший общий делитель (НОД) всех чисел в массиве равен 1, то массив считается хорошим.
2⃣ Если НОД всех чисел больше 1, то массив не считается хорошим
3⃣ Получить сумму, равную 1, умножая и складывая элементы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан массив nums из целых положительных чисел. Ваша задача - выбрать некоторое подмножество nums, умножить каждый элемент на целое число и сложить все эти числа.Массив считается хорошим, если из него можно получить сумму, равную 1, при любом возможном подмножестве и множителе. Верните True, если массив хороший, иначе верните False.
Пример:
Input: nums = [12,5,7,23]
Output: true
import java.util.Arrays;
public class Solution {
public boolean isGoodArray(int[] nums) {
int gcd = nums[0];
for (int num : nums) {
gcd = gcd(gcd, num);
if (gcd == 1) return true;
}
return gcd == 1;
}
private int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
📅 Осталось 7 дней до конца краудфандинга
Мы на финишной прямой!
Если ты планировал присоединиться, но ещё не успел, сейчас идеальный момент.
Вознаграждения за поддержку:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу.
➕ Приглашение на закрытое бета-тестирование
👉 Поддержать easyoffer 2.0
Не откладывай на последний момент
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Мы на финишной прямой!
Если ты планировал присоединиться, но ещё не успел, сейчас идеальный момент.
Вознаграждения за поддержку:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу.
➕ Приглашение на закрытое бета-тестирование
👉 Поддержать easyoffer 2.0
Не откладывай на последний момент
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Задача: 1197. Minimum Knight Moves
Сложность: medium
На бесконечной шахматной доске с координатами от -бесконечности до +бесконечности у вас есть конь на клетке [0, 0].
У коня есть 8 возможных ходов. Каждый ход представляет собой два квадрата в кардинальном направлении, затем один квадрат в ортогональном направлении.
Верните минимальное количество шагов, необходимых для перемещения коня на клетку [x, y]. Гарантируется, что ответ существует.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация структур данных:
Инициализируйте две очереди для хранения координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
Инициализируйте две карты для хранения посещенных координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
2⃣ Реализация двунаправленного поиска в ширину (BFS):
Выполняйте шаги из очередей, расширяя круги поиска как от начальной, так и от конечной точки.
Если круги пересекаются, возвращайте сумму расстояний до точки пересечения.
3⃣ Расширение кругов поиска:
Для каждой текущей точки из очередей расширяйте круг поиска по всем возможным ходам коня.
Обновляйте расстояния и добавляйте новые точки в очереди, если они еще не были посещены.
Увеличивайте units на значение, извлеченное из кучи.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
На бесконечной шахматной доске с координатами от -бесконечности до +бесконечности у вас есть конь на клетке [0, 0].
У коня есть 8 возможных ходов. Каждый ход представляет собой два квадрата в кардинальном направлении, затем один квадрат в ортогональном направлении.
Верните минимальное количество шагов, необходимых для перемещения коня на клетку [x, y]. Гарантируется, что ответ существует.
Пример:
Input: x = 5, y = 5
Output: 4
Explanation: [0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]
Инициализируйте две очереди для хранения координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
Инициализируйте две карты для хранения посещенных координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
Выполняйте шаги из очередей, расширяя круги поиска как от начальной, так и от конечной точки.
Если круги пересекаются, возвращайте сумму расстояний до точки пересечения.
Для каждой текущей точки из очередей расширяйте круг поиска по всем возможным ходам коня.
Обновляйте расстояния и добавляйте новые точки в очереди, если они еще не были посещены.
Увеличивайте units на значение, извлеченное из кучи.
class Solution {
public int minKnightMoves(int x, int y) {
int[][] offsets = {{1, 2}, {2, 1}, {2, -1}, {1, -2},
{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}};
Deque<int[]> originQueue = new LinkedList<>();
originQueue.addLast(new int[]{0, 0, 0});
Map<String, Integer> originDistance = new HashMap<>();
originDistance.put("0,0", 0);
Deque<int[]> targetQueue = new LinkedList<>();
targetQueue.addLast(new int[]{x, y, 0});
Map<String, Integer> targetDistance = new HashMap<>();
targetDistance.put(x + "," + y, 0);
while (true) {
int[] origin = originQueue.removeFirst();
String originXY = origin[0] + "," + origin[1];
if (targetDistance.containsKey(originXY)) {
return origin[2] + targetDistance.get(originXY);
}
int[] target = targetQueue.removeFirst();
String targetXY = target[0] + "," + target[1];
if (originDistance.containsKey(targetXY)) {
return target[2] + originDistance.get(targetXY);
}
for (int[] offset : offsets) {
int[] nextOrigin = new int[]{origin[0] + offset[0], origin[1] + offset[1]};
String nextOriginXY = nextOrigin[0] + "," + nextOrigin[1];
if (!originDistance.containsKey(nextOriginXY)) {
originQueue.addLast(new int[]{nextOrigin[0], nextOrigin[1], origin[2] + 1});
originDistance.put(nextOriginXY, origin[2] + 1);
}
int[] nextTarget = new int[]{target[0] + offset[0], target[1] + offset[1]};
String nextTargetXY = nextTarget[0] + "," + nextTarget[1];
if (!targetDistance.containsKey(nextTargetXY)) {
targetQueue.addLast(new int[]{nextTarget[0], nextTarget[1], target[2] + 1});
targetDistance.put(nextTargetXY, target[2] + 1);
}
}
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 90. Subsets II
Сложность: medium
Дан массив целых чисел nums, который может содержать повторяющиеся элементы. Верните все возможные подмножества (степенной набор).
Результирующий набор не должен содержать дублирующихся подмножеств. Возвращаемый результат может быть в любом порядке.
Пример:
👨💻 Алгоритм:
1⃣ Отсортировать массив numsтак, чтобы элементы шли подряд были одинаковыми — это поможет избежать дубликатов.
2⃣ Сгенерировать все возможные подмножества с помощью битовой маски от 0до 2^n - 1, где n— длина массива.
3⃣ Для каждого подмножества формируем строковый «хеш» и сохраняем уже добавленные подмножества в Set, чтобы не создавать дубликаты.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел nums, который может содержать повторяющиеся элементы. Верните все возможные подмножества (степенной набор).
Результирующий набор не должен содержать дублирующихся подмножеств. Возвращаемый результат может быть в любом порядке.
Пример:
Input: nums = [1,2,2]
Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> subsets = new ArrayList();
int n = nums.length;
Arrays.sort(nums);
int maxNumberOfSubsets = (int) Math.pow(2, n);
Set<String> seen = new HashSet<>();
for (int subsetIndex = 0; subsetIndex < maxNumberOfSubsets; subsetIndex++) {
List<Integer> currentSubset = new ArrayList();
StringBuilder hashcode = new StringBuilder();
for (int j = 0; j < n; j++) {
int mask = 1 << j;
int isSet = mask & subsetIndex;
if (isSet != 0) {
currentSubset.add(nums[j]);
hashcode.append(nums[j]).append(",");
}
}
if (!seen.contains(hashcode.toString())) {
seen.add(hashcode.toString());
subsets.add(currentSubset);
}
}
return subsets;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1244. Design A Leaderboard
Сложность: medium
Разработайте класс Leaderboard, который содержит 3 функции: addScore(playerId, score): Обновляет таблицу лидеров, добавляя счет к счету данного игрока. Если в таблице лидеров нет игрока с таким id, добавьте его в таблицу лидеров с заданным счетом. top(K): Возвращает сумму очков K лучших игроков. reset(playerId): Сбрасывает счет игрока с заданным идентификатором в 0 (другими словами, стирает его из таблицы лидеров). Гарантируется, что игрок был добавлен в таблицу лидеров до вызова этой функции. Изначально таблица лидеров пуста.
Пример:
👨💻 Алгоритм:
1⃣ addScore(playerId, score):
Если игрок уже существует в таблице лидеров, добавляем к его текущему счету новое значение.
Если игрок не существует, добавляем его с заданным счетом.
2⃣ top(K):
Сортируем игроков по их счету в порядке убывания.
Возвращаем сумму очков K лучших игроков.
3⃣ reset(playerId):
Устанавливаем счет игрока в 0.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Разработайте класс Leaderboard, который содержит 3 функции: addScore(playerId, score): Обновляет таблицу лидеров, добавляя счет к счету данного игрока. Если в таблице лидеров нет игрока с таким id, добавьте его в таблицу лидеров с заданным счетом. top(K): Возвращает сумму очков K лучших игроков. reset(playerId): Сбрасывает счет игрока с заданным идентификатором в 0 (другими словами, стирает его из таблицы лидеров). Гарантируется, что игрок был добавлен в таблицу лидеров до вызова этой функции. Изначально таблица лидеров пуста.
Пример:
Input:
["Leaderboard","addScore","addScore","addScore","addScore","addScore","top","reset","reset","addScore","top"]
[[],[1,73],[2,56],[3,39],[4,51],[5,4],[1],[1],[2],[2,51],[3]]
Output:
[null,null,null,null,null,null,73,null,null,null,141]
Если игрок уже существует в таблице лидеров, добавляем к его текущему счету новое значение.
Если игрок не существует, добавляем его с заданным счетом.
Сортируем игроков по их счету в порядке убывания.
Возвращаем сумму очков K лучших игроков.
Устанавливаем счет игрока в 0.
import java.util.*;
public class Leaderboard {
private Map<Integer, Integer> scores;
public Leaderboard() {
scores = new HashMap<>();
}
public void addScore(int playerId, int score) {
scores.put(playerId, scores.getOrDefault(playerId, 0) + score);
}
public int top(int K) {
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
maxHeap.addAll(scores.values());
int sum = 0;
for (int i = 0; i < K && !maxHeap.isEmpty(); i++) {
sum += maxHeap.poll();
}
return sum;
}
public void reset(int playerId) {
scores.put(playerId, 0);
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 994. Rotting Oranges
Сложность: medium
Дан m x n сетка, где каждая ячейка может иметь одно из трех значений:
0, представляющее пустую ячейку,
1, представляющее свежий апельсин,
2, представляющее гнилой апельсин.
Каждую минуту любой свежий апельсин, который находится в 4-х направленно смежной ячейке с гнилым апельсином, становится гнилым.
Верните минимальное количество минут, которые должны пройти, пока в ячейке не останется свежих апельсинов. Если это невозможно, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация очереди и подсчет апельсинов:
Пройдите по всей сетке, добавьте все гнилые апельсины в очередь и подсчитайте общее количество свежих апельсинов.
Если нет свежих апельсинов, верните 0.
2⃣ Использование BFS для распространения гнили:
Выполняйте BFS, начиная с всех гнилых апельсинов, добавленных в очередь.
Каждый раз, когда апельсин становится гнилым, уменьшайте счетчик свежих апельсинов.
Если свежих апельсинов больше не осталось, верните текущее количество минут.
3⃣ Проверка оставшихся свежих апельсинов:
Если после завершения BFS все еще остаются свежие апельсины, верните -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан m x n сетка, где каждая ячейка может иметь одно из трех значений:
0, представляющее пустую ячейку,
1, представляющее свежий апельсин,
2, представляющее гнилой апельсин.
Каждую минуту любой свежий апельсин, который находится в 4-х направленно смежной ячейке с гнилым апельсином, становится гнилым.
Верните минимальное количество минут, которые должны пройти, пока в ячейке не останется свежих апельсинов. Если это невозможно, верните -1.
Пример:
Input: grid = [[2,1,1],[0,1,1],[1,0,1]]
Output: -1
Explanation: The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally.
Пройдите по всей сетке, добавьте все гнилые апельсины в очередь и подсчитайте общее количество свежих апельсинов.
Если нет свежих апельсинов, верните 0.
Выполняйте BFS, начиная с всех гнилых апельсинов, добавленных в очередь.
Каждый раз, когда апельсин становится гнилым, уменьшайте счетчик свежих апельсинов.
Если свежих апельсинов больше не осталось, верните текущее количество минут.
Если после завершения BFS все еще остаются свежие апельсины, верните -1.
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
public int orangesRotting(int[][] grid) {
Queue<int[]> queue = new LinkedList<>();
int freshCount = 0;
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 2) {
queue.offer(new int[]{i, j});
} else if (grid[i][j] == 1) {
freshCount++;
}
}
}
if (freshCount == 0) return 0;
int minutes = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] point = queue.poll();
for (int[] dir : directions) {
int ni = point[0] + dir[0], nj = point[1] + dir[1];
if (ni >= 0 && ni < grid.length && nj >= 0 && nj < grid[0].length && grid[ni][nj] == 1) {
grid[ni][nj] = 2;
freshCount--;
queue.offer(new int[]{ni, nj});
}
}
}
if (!queue.isEmpty()) {
minutes++;
}
}
return freshCount == 0 ? minutes : -1;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Задача: 1168. Optimize Water Distribution in a Village
Сложность: hard
В деревне есть n домов. Мы хотим обеспечить все дома водой, строя колодцы и прокладывая трубы.
Для каждого дома i мы можем либо построить колодец внутри него непосредственно с затратами wells[i - 1] (обратите внимание на -1 из-за нумерации с нуля), либо провести воду из другого колодца с помощью трубы. Затраты на прокладку труб между домами даны в массиве pipes, где каждый pipes[j] = [house1j, house2j, costj] представляет собой стоимость соединения дома house1j и дома house2j с помощью трубы. Соединения двунаправленные, и между одними и теми же домами могут быть несколько допустимых соединений с разными затратами.
Верните минимальные оhttps://leetcode.com/problems/optimize-water-distribution-in-a-village/Figures/1168/PrimAlgDemo.gifбщие затраты на обеспечение всех домов водой.
Пример:
👨💻 Алгоритм:
1⃣ Представление графа: Постройте список смежности для представления графа, где вершины и ребра соответствуют домам и трубам. Список смежности можно представить в виде списка списков или словаря списков.
2⃣ Набор для вершин: Используйте набор для поддержания всех вершин, добавленных в окончательное минимальное остовное дерево (MST) во время его построения. С помощью набора можно определить, была ли вершина уже добавлена или нет.
3⃣ Очередь с приоритетом (куча): Используйте кучу для реализации жадной стратегии. На каждом шаге определяйте лучшее ребро для добавления на основе стоимости его добавления в дерево. Куча позволяет извлекать минимальный элемент за константное время и удалять минимальный элемент за логарифмическое время. Это идеально подходит для нашей задачи повторного нахождения ребра с наименьшей стоимостью.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
В деревне есть n домов. Мы хотим обеспечить все дома водой, строя колодцы и прокладывая трубы.
Для каждого дома i мы можем либо построить колодец внутри него непосредственно с затратами wells[i - 1] (обратите внимание на -1 из-за нумерации с нуля), либо провести воду из другого колодца с помощью трубы. Затраты на прокладку труб между домами даны в массиве pipes, где каждый pipes[j] = [house1j, house2j, costj] представляет собой стоимость соединения дома house1j и дома house2j с помощью трубы. Соединения двунаправленные, и между одними и теми же домами могут быть несколько допустимых соединений с разными затратами.
Верните минимальные оhttps://leetcode.com/problems/optimize-water-distribution-in-a-village/Figures/1168/PrimAlgDemo.gifбщие затраты на обеспечение всех домов водой.
Пример:
Input: n = 3, wells = [1,2,2], pipes = [[1,2,1],[2,3,1]]
Output: 3
Explanation: The image shows the costs of connecting houses using pipes.
The best strategy is to build a well in the first house with cost 1 and connect the other houses to it with cost 2 so the total cost is 3.
class Solution {
public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
PriorityQueue<int[]> edgesHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]);
List<List<int[]>> graph = new ArrayList<>(n + 1);
for (int i = 0; i < n + 1; ++i) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < wells.length; ++i) {
graph.get(0).add(new int[]{wells[i], i + 1});
edgesHeap.add(new int[]{wells[i], i + 1});
}
for (int[] pipe : pipes) {
int house1 = pipe[0];
int house2 = pipe[1];
int cost = pipe[2];
graph.get(house1).add(new int[]{cost, house2});
graph.get(house2).add(new int[]{cost, house1});
}
Set<Integer> mstSet = new HashSet<>();
mstSet.add(0);
int totalCost = 0;
while (mstSet.size() < n + 1) {
int[] edge = edgesHeap.poll();
int cost = edge[0];
int nextHouse = edge[1];
if (mstSet.contains(nextHouse)) continue;
mstSet.add(nextHouse);
totalCost += cost;
for (int[] neighborEdge : graph.get(nextHouse)) {
if (!mstSet.contains(neighborEdge[1])) {
edgesHeap.add(neighborEdge);
}
}
}
return totalCost;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 110. Balanced Binary Tree
Сложность: easy
Дано бинарное дерево, определите, является ли оно
сбалансированным по высоте.
Пример:
👨💻 Алгоритм:
1⃣ Сначала мы определяем функцию height, которая для любого узла p в дереве T возвращает:
-1, если p является пустым поддеревом, т.е. null;
1 + max(height(p.left), height(p.right)) в противном случае.
2⃣ Теперь, когда у нас есть метод для определения высоты дерева, остается только сравнить высоты детей каждого узла. Дерево T с корнем r является сбалансированным тогда и только тогда, когда высоты его двух детей отличаются не более чем на 1 и поддеревья каждого ребенка также сбалансированы.
3⃣ Следовательно, мы можем сравнить высоты двух дочерних поддеревьев, а затем рекурсивно проверить каждое из них:
Если root == NULL, возвращаем true.
Если abs(height(root.left) - height(root.right)) > 1, возвращаем false. В противном случае возвращаем isBalanced(root.left) && isBalanced(root.right).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано бинарное дерево, определите, является ли оно
сбалансированным по высоте.
Пример:
Input: root = [3,9,20,null,null,15,7]
Output: true
-1, если p является пустым поддеревом, т.е. null;
1 + max(height(p.left), height(p.right)) в противном случае.
Если root == NULL, возвращаем true.
Если abs(height(root.left) - height(root.right)) > 1, возвращаем false. В противном случае возвращаем isBalanced(root.left) && isBalanced(root.right).
class Solution {
private int height(TreeNode root) {
if (root == null) {
return -1;
}
return 1 + Math.max(height(root.left), height(root.right));
}
public boolean isBalanced(TreeNode root) {
if (root == null) {
return true;
}
return (
Math.abs(height(root.left) - height(root.right)) < 2 &&
isBalanced(root.left) &&
isBalanced(root.right)
);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1