Java | LeetCode

channel icon
Сайт: easyoffer.ru

Условия размещения

Цена за 48 часов в ленте 2650,00
Цена за 1 час закрепления N/A
Взаимопиар Нет
Дополнительные условия рекламы Отсутствуют
+2
4 011
подписчиков
-7
762
охват 1 публикации
0
~3
постов / день
-0,2%
19,0%
ERR % ?

Статистика

Последние публикации

Java | LeetCode
7 сентября 2024 г. 12:07
#medium
Задача: 207. Course Schedule

Всего у вас есть numCourses курсов, которые нужно пройти, пронумерованных от 0 до numCourses - 1. Вам дан массив prerequisites, где prerequisites[i] = [ai, bi] указывает на то, что вы должны сначала пройти курс bi, если хотите взять курс ai.

Например, пара [0, 1] указывает на то, что для прохождения курса 0 сначала нужно пройти курс 1.
Верните true, если вы можете завершить все курсы. В противном случае верните false.

Пример:
Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.


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

1️⃣Создайте массив indegree длины n, где indegree[x] хранит количество входящих рёбер в узел x. Создайте список смежности adj, в котором adj[x] содержит все узлы с входящим ребром от узла x, то есть соседей узла x. Создайте этот список смежности, итерируя prerequisites. Для каждого prerequisites добавьте ребро от prerequisites[1] к prerequisites[0] и увеличьте indegree prerequisites[0] на 1.

2️⃣Инициализируйте очередь целых чисел q и начните алгоритм BFS, перемещаясь от листовых узлов к родительским узлам. Начните обход BFS, поместив все листовые узлы (indegree равное 0) в очередь. Создайте целочисленную переменную nodesVisited = 0 для подсчета количества посещенных узлов.

3️⃣Пока очередь не пуста:
Извлеките первый узел из очереди.
Увеличьте nodesVisited на 1.
Для каждого соседа (узлы, которые имеют входящее ребро от узла) узла уменьшите indegree[neighbor] на 1, чтобы удалить ребро node -> neighbor.
Если indegree[neighbor] == 0, это означает, что neighbor ведет себя как листовой узел, поэтому добавьте neighbor в очередь.
Если количество посещенных узлов меньше общего количества узлов, то есть nodesVisited < n, верните false, так как должен быть цикл. В противном случае, если nodesVisited == numCourses, верните true. Можно сократить это до просто возвращения nodesVisited == numCourses.

😎 Решение:
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
int[] indegree = new int[numCourses];
List> adj = new ArrayList<>(numCourses);

for (int i = 0; i < numCourses; i++) {
adj.add(new ArrayList<>());
}

for (int[] prerequisite : prerequisites) {
adj.get(prerequisite[1]).add(prerequisite[0]);
indegree[prerequisite[0]]++;
}

Queue queue = new LinkedList<>();
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) {
queue.offer(i);
}
}

int nodesVisited = 0;
while (!queue.isEmpty()) {
int node = queue.poll();
nodesVisited++;

for (int neighbor : adj.get(node)) {
indegree[neighbor]--;
if (indegree[neighbor] == 0) {
queue.offer(neighbor);
}
}
}

return nodesVisited == numCourses;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
6 сентября 2024 г. 19:07
#easy
Задача: 206. Reverse Linked List

Дан односвязный список, разверните этот список и верните развернутый список.

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


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

1️⃣Инициализируйте две переменные: prev как nullptr и curr как head списка. Эти переменные будут использоваться для отслеживания предыдущего и текущего узлов в процессе разворота списка.

2️⃣Пройдитесь по списку с помощью цикла:
Сохраните ссылку на следующий узел curr в переменную nextTemp.
Измените ссылку next текущего узла curr на prev, чтобы развернуть направление ссылки.
Переместите prev на текущий узел curr и переместите curr на следующий узел nextTemp.

3️⃣После завершения цикла верните prev как новую голову развернутого списка.

😎 Решение:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
6 сентября 2024 г. 12:07
#medium
Задача: 204. Count Primes

Дано целое число n, верните количество простых чисел, которые строго меньше n.

Пример:
Input: n = 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.


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

1️⃣Создайте список последовательных целых чисел от 2 до n: (2, 3, 4, ..., n). Пусть p будет переменной, используемой во внешнем цикле, проходящем от 2 до n. Изначально p равно 2, самому маленькому простому числу.

2️⃣Перечислите кратные числа p, считая с шагом p от pp до n и отметьте их в списке (это будут pp, pp + p, pp + 2*p и т.д.; само число p должно быть простым). Найдите наименьшее число в списке, большее p, которое не отмечено. Если такого числа нет, остановитесь. В противном случае, пусть p теперь равно этому новому числу (следующее простое) и повторите шаг 2.

3️⃣Когда алгоритм завершится, все оставшиеся числа, которые не отмечены, являются простыми.

😎 Решение:
class Solution {
public int countPrimes(int n) {
if (n <= 2) {
return 0;
}

boolean[] numbers = new boolean[n];
for (int p = 2; p <= (int) Math.sqrt(n); ++p) {
if (numbers[p] == false) {
for (int j = p * p; j < n; j += p) {
numbers[j] = true;
}
}
}

int numberOfPrimes = 0;
for (int i = 2; i < n; i++) {
if (numbers[i] == false) {
++numberOfPrimes;
}
}

return numberOfPrimes;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
5 сентября 2024 г. 19:07
#easy
Задача: 203. Remove Linked List Elements

Для заданного начала связного списка и целого числа val удалите все узлы связного списка, у которых Node.val равно val, и верните новое начало списка.

Пример:
Input: head = [1,2,6,3,4,5,6], val = 6
Output: [1,2,3,4,5]


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

1️⃣Инициализируйте сторожевой узел как ListNode(0) и установите его новым началом: sentinel.next = head. Инициализируйте два указателя для отслеживания текущего узла и его предшественника: curr и prev.

2️⃣Пока curr не является нулевым указателем, сравните значение текущего узла со значением для удаления. Если значения равны, удалите текущий узел: prev.next = curr.next, иначе установите предшественника равным текущему узлу. Переместитесь к следующему узлу: curr = curr.next.

3️⃣Верните sentinel.next.

😎 Решение:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode sentinel = new ListNode(0);
sentinel.next = head;

ListNode prev = sentinel, curr = head;
while (curr != null) {
if (curr.val == val) prev.next = curr.next;
else prev = curr;
curr = curr.next;
}
return sentinel.next;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
5 сентября 2024 г. 12:07
#easy
Задача: 202. Happy Number

Напишите алгоритм для определения, является ли число n счастливым.

Счастливое число определяется следующим процессом:

Начиная с любого положительного целого числа, замените число суммой квадратов его цифр.
Повторяйте процесс, пока число не станет равным 1 (где оно и останется), или пока оно бесконечно не будет циклически повторяться в цикле, который не включает 1.
Те числа, для которых этот процесс завершается 1, являются счастливыми.
Верните true, если n является счастливым числом, и false, если нет.

Пример:
Input: n = 2
Output: false


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

1️⃣Для заданного числа n определите следующее число в последовательности: используйте операторы деления и взятия остатка для последовательного извлечения цифр из числа, пока не закончатся все цифры. Каждую извлеченную цифру возводите в квадрат и суммируйте полученные значения. Это техника "последовательного извлечения цифр" является полезным инструментом для решения множества задач.

2️⃣Отслеживайте цепочку чисел и определяйте, не вошли ли вы в цикл, используя структуру данных HashSet. Каждый раз, генерируя следующее число в цепочке, проверяйте, присутствует ли оно уже в HashSet.

3️⃣Если числа нет в HashSet, добавьте его туда. Если число уже есть в HashSet, это означает, что вы находитесь в цикле, и следует вернуть false. HashSet используется вместо Vector, List или Array, потому что проверка присутствия числа в HashSet занимает время O(1), тогда как в других структурах данных это займет время O(n). Правильный выбор структур данных является ключевым элементом решения подобных задач.

😎 Решение:
class Solution {
private int getNext(int n) {
int totalSum = 0;
while (n > 0) {
int d = n % 10;
n = n / 10;
totalSum += d * d;
}
return totalSum;
}

public boolean isHappy(int n) {
Set seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getNext(n);
}
return n == 1;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
5 сентября 2024 г. 10:00
Расширьте свои навыки в программировании с бесплатным мини-курсом по Java! Научитесь создавать Telegram-ботов, разрабатывать программы для обработки данных и строить чаты на фреймворке Spring. Не упустите шанс — начните обучение уже сегодня: 👉 https://epic.st/m6-1u?erid=2VtzqxacvBP

Формат мини-курса отлично подойдёт для обучения из любой точки мира: смотрите видео в удобное время и закрепляйте навыки на практике.

🎁 За время обучения вы получите 5 полезных материалов в подарок, сертификат на скидку 10 000 рублей на любой курс, персональную карьерную консультацию и доступ к изучению английского языка в Skillbox на год.

До встречи на мини-курсе. Старт после регистрации!

Реклама. ЧОУ ДПО «Образовательные технологии «Скилбокс (Коробка навыков)», ИНН: 9704088880
Java | LeetCode
4 сентября 2024 г. 19:07
#easy
Задача: 202. Happy Number

Напишите алгоритм для определения, является ли число n счастливым.

Счастливое число определяется следующим образом:

1. Начинаем с любого положительного числа и заменяем его на сумму квадратов его цифр.
2. Повторяем процесс до тех пор, пока число не станет равным 1 (где оно останется), или пока оно не зациклится бесконечно, не достигая 1.
3. Числа, для которых этот процесс заканчивается на 1, являются счастливыми.
4. Верните true, если n является счастливым числом, и false, если нет.

Пример:
Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1


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

1️⃣Определите следующее число для заданного числа n. Это можно сделать, используя операции деления и взятия по модулю, чтобы последовательно извлекать цифры из числа, пока они не закончатся, затем возводить каждую извлечённую цифру в квадрат и суммировать их. Внимательно посмотрите на код для этого, "извлечение цифр по одной" — полезная техника, которую вы будете использовать для решения множества различных задач.

2️⃣Следите за цепочкой чисел и обнаруживайте, если мы вошли в цикл. Это можно сделать с помощью HashSet. Каждый раз, когда мы генерируем следующее число в цепочке, мы проверяем, есть ли оно уже в нашем HashSet. Если его нет в HashSet, мы добавляем его. Если оно уже в HashSet, это означает, что мы находимся в цикле и должны вернуть false.

3️⃣Мы используем HashSet, а не Vector, List или Array, потому что мы многократно проверяем, находятся ли числа в нём. Проверка, находится ли число в HashSet, занимает время O(1), тогда как для других структур данных это занимает время O(n). Выбор правильных структур данных — важная часть решения этих задач.

😎 Решение:
class Solution {
private int getNext(int n) {
int totalSum = 0;
while (n > 0) {
int d = n % 10;
n = n / 10;
totalSum += d * d;
}
return totalSum;
}

public boolean isHappy(int n) {
Set seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getNext(n);
}
return n == 1;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
4 сентября 2024 г. 17:00
🚨 Не знаешь как подготовиться к собесу по Java? Хватит гадать, бери готовые ответы!

Очень часто на интервью по Java задают одни и те же вопросы по базовым темам, вне зависимости от копании и грейда!

Хотим порекомендовать новый материал от Павла Сорокина, в котором он агрегировал свой опыт прохождения собеседований и менторства и подробно разобрал самые частые вопросы по Java Core и многопоточности в одном видео-гайде.

🔥 Что внутри гайда?

📍Обзор самых популярных вопросов на собеседованиях по Java Core и многопоточности.

📍Пошаговые объяснения и лайфхаки, как правильно отвечать.

📍Запись успешного собеса на Junior в один из крупнейших российских финтехов.

Благодаря этому гайду ученики Паши легко проходят собеседования и получают офферы на 150-350 тысяч в крупнейшие компании. Теперь твоя очередь! Делимся видео-гайдом совершенно бесплатно 🎁

🚀 Переходи в бота, забирай гайд и будь готов к любому повороту на собесе!👇🏻
https://t.me/JavaLearnBot?start=c1724626210163-31-ds
Java | LeetCode
4 сентября 2024 г. 12:07
#medium
Задача: 201. Bitwise AND of Numbers Range

Даны два целых числа left и right, которые представляют диапазон [left, right], верните побитовое И всех чисел в этом диапазоне включительно.

Пример:
Input: left = 5, right = 7
Output: 4


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

1️⃣Сдвигать left и right вправо, пока они не станут равными.

2️⃣Подсчитать количество сдвигов.

3️⃣Сдвинуть left влево на количество сдвигов и вернуть результат.

😎 Решение:
class Solution {
public int rangeBitwiseAnd(int m, int n) {
int shift = 0;
while (m < n) {
m >>= 1;
n >>= 1;
++shift;
}
return m << shift;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
4 сентября 2024 г. 10:00
Все надоело и пропал интерес, чувствуешь себя амебой и хочется только залипать в телефоне. Бывает?

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

✔️ Как научиться отвлекаться от работы и отдыхать?
✔️ Как совместить кучу рабочих задач и время с семьей?
✔️ Как справиться с прокрастинацией?
✔️ Как не растерять запал, даже если начальник и коллеги 💩 и кажется, что ничего не выходит?

Подписывайтесь на канал @vadimpetrov_psy и научитесь работать без упахивания, выгорания и ущерба для личной жизни!

👨🏻‍💻 Псс. Заходите в закреп канала - там много полезного, и даже бесплатный мини-курс.

https://t.me/+_f2HiZ99wxswZGRihttps://t.me/+_f2HiZ99wxswZGRi
Java | LeetCode
3 сентября 2024 г. 19:07
#medium
Задача: 200. Number of Islands

Дана двумерная бинарная сетка размером m x n, представляющая карту из '1' (земля) и '0' (вода). Верните количество островов.

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

Пример:
Input: grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
Output: 1


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

1️⃣Линейно просканируйте двумерную карту, если узел содержит '1', то это корневой узел, который запускает поиск в глубину (DFS).

2️⃣Во время выполнения DFS каждый посещённый узел следует установить в '0', чтобы пометить его как посещённый.

3️⃣Подсчитайте количество корневых узлов, запускающих DFS. Это количество будет равно количеству островов, так как каждый DFS, начинающийся с какого-либо корня, идентифицирует остров.

😎 Решение:
class Solution {
void dfs(char[][] grid, int r, int c) {
int nr = grid.length;
int nc = grid[0].length;

if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {
return;
}

grid[r][c] = '0';
dfs(grid, r - 1, c);
dfs(grid, r + 1, c);
dfs(grid, r, c - 1);
dfs(grid, r, c + 1);
}

public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}

int nr = grid.length;
int nc = grid[0].length;
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
dfs(grid, r, c);
}
}
}

return num_islands;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
3 сентября 2024 г. 12:07
#medium
Задача: 199. Binary Tree Right Side View

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

Пример:
Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]


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

1️⃣Инициализируйте список правого обзора rightside. Инициализируйте две очереди: одну для текущего уровня и одну для следующего. Добавьте корень в очередь nextLevel.

2️⃣Пока очередь nextLevel не пуста:
Инициализируйте текущий уровень: currLevel = nextLevel и очистите очередь следующего уровня nextLevel.
Пока очередь текущего уровня не пуста:
Извлеките узел из очереди текущего уровня.
Добавьте сначала левый, а затем правый дочерний узел в очередь nextLevel.
Теперь очередь currLevel пуста, и узел, который у нас есть, является последним и составляет часть правого обзора. Добавьте его в rightside.

3️⃣Верните rightside.

😎 Решение:
class Solution {
public List rightSideView(TreeNode root) {
if (root == null) return new ArrayList();

ArrayDeque nextLevel = new ArrayDeque() {
{
offer(root);
}
};
ArrayDeque currLevel = new ArrayDeque();
List rightside = new ArrayList();

TreeNode node = null;
while (!nextLevel.isEmpty()) {
currLevel = nextLevel;
nextLevel = new ArrayDeque<>();

while (!currLevel.isEmpty()) {
node = currLevel.poll();

if (node.left != null) nextLevel.offer(node.left);
if (node.right != null) nextLevel.offer(node.right);
}

if (currLevel.isEmpty()) rightside.add(node.val);
}
return rightside;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
3 сентября 2024 г. 10:00
🥰 Как улучшить свой кодКак улучшить свой код 🥰

Настрой среду, в которой ты работаешь!Настрой среду, в которой ты работаешь!

🥰 Многие программисты пишут код на настройках по умолчанию - ошибка.

🥰🥰 Не подключают плагины, которые ускорят работу и увеличат эффективность - фатальная ошибка.

👩‍💻👩‍💻 Канал Visual Studio Сode | ПлагиныVisual Studio Сode | Плагины сделает твою рабочую среду универсальным и мощным инструментом.

🥰🥰 Повышай свою эффективность и подписывайся на канал Visual Studio Сode | ПлагиныПовышай свою эффективность и подписывайся на канал Visual Studio Сode | Плагины
Java | LeetCode
2 сентября 2024 г. 19:07
#medium
Задача: 198. House Robber

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

Учитывая целочисленный массив nums, представляющий сумму денег в каждом доме, верните максимальную сумму денег, которую вы можете ограбить этой ночью, не подняв тревогу.

Пример:
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.


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

1️⃣Определите функцию robFrom(), которая принимает индекс дома, который грабитель должен осмотреть, и массив nums, необходимый для вычислений. На каждом шаге рекурсивного вызова у грабителя есть два варианта: ограбить текущий дом или нет.

2️⃣Если грабитель выбирает ограбить текущий дом, он должен пропустить следующий, т.е. вызвать robFrom(i + 2, nums). Ответ будет равен значению robFrom(i + 2, nums) плюс сумма, которую грабитель получит, ограбив текущий дом, т.е. nums[i]. В противном случае он может перейти к следующему дому и вернуть прибыль, которую он получит в подзадаче, т.е. robFrom(i + 1, nums).

3️⃣Нужно найти, сохранить в кэше и вернуть максимум из этих двух вариантов на каждом шаге. robFrom(0, nums) даст ответ на всю задачу.

😎 Решение:
class Solution {
private int[] memo;

public int rob(int[] nums) {
this.memo = new int[100];
Arrays.fill(this.memo, -1);
return this.robFrom(0, nums);
}

private int robFrom(int i, int[] nums) {
if (i >= nums.length) {
return 0;
}
if (this.memo[i] > -1) {
return this.memo[i];
}
int ans = Math.max(
this.robFrom(i + 1, nums),
this.robFrom(i + 2, nums) + nums[i]
);
this.memo[i] = ans;
return ans;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
2 сентября 2024 г. 12:07
#easy
Задача: 191. Number of 1 Bits

Напишите функцию, которая принимает бинарное представление положительного целого числа и возвращает количество установленных битов (также известных как вес Хэмминга).

Пример:
Input: n = 11

Output: 3

Explanation:

The input binary string 1011 has a total of three set bits.


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

1️⃣Решение простое: проверяем каждый из 32 битов числа. Если бит равен 1, увеличиваем количество 1-битов на единицу.

2️⃣Для проверки i-го бита числа используем битовую маску. Начинаем с маски m=1, так как двоичное представление 1 это 0000 0000 0000 0000 0000 0000 0000 0001. Логическое И между любым числом и маской 1 дает нам младший бит этого числа.

3️⃣Для проверки следующего бита сдвигаем маску влево на один:
0000 0000 0000 0000 0000 0000 0000 0010 и так далее.

😎 Решение:
public int hammingWeight(int n) {
int bits = 0;
int mask = 1;
for (int i = 0; i < 32; i++) {
if ((n & mask) != 0) {
bits++;
}
mask <<= 1;
}
return bits;
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
1 сентября 2024 г. 19:07
#easy
Задача: 190. Reverse Bits

Переверните биты заданного 32-битного беззнакового целого числа.

Пример:
Input: n = 00000010100101000001111010011100
Output: 964176192 (00111001011110000010100101000000)
Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
Example 2:


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

1️⃣Итерируем по байтам целого числа, используя побитовую операцию И (n & 0xff) с маской 11111111, чтобы извлечь крайний правый байт числа.

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

3️⃣В функции reverseByte(byte) используем технику мемоизации, которая сохраняет результат функции и возвращает его непосредственно при последующих вызовах с тем же входным значением. Мемоизация — это компромисс между использованием памяти и объемом вычислений.

😎 Решение:
class Solution {
private int reverseByte(int byteVal, Map cache) {
if (cache.containsKey(byteVal)) {
return cache.get(byteVal);
}
int value = (int)(((byteVal * 0x0202020202L) & 0x010884422010L) % 1023);
cache.put(byteVal, value);
return value;
}
public int reverseBits(int n) {
int ret = 0;
int power = 24;
Map cache = new HashMap<>();
while (n != 0) {
ret += reverseByte(n & 0xff, cache) << power;
n >>>= 8; // Use unsigned shift
power -= 8;
}
return ret;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
1 сентября 2024 г. 12:07
#medium
Задача: 189. Rotate Array

Для целочисленного массива nums, поверните массив вправо на k шагов, где k — неотрицательное число.

Пример:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]


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

1️⃣Создаем дополнительный массив, в который будем помещать каждый элемент исходного массива на его новую позицию. Элемент на позиции i в исходном массиве будет размещен на индексе (i+k) % длина массива.

2️⃣Копируем элементы из нового массива в исходный массив, сохраняя новый порядок элементов.

3️⃣Заменяем исходный массив полученным результатом, завершая процесс поворота массива.

😎 Решение:
class Solution {
public void rotate(int[] nums, int k) {
int[] a = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
a[(i + k) % nums.length] = nums[i];
}
for (int i = 0; i < nums.length; i++) {
nums[i] = a[i];
}
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
31 августа 2024 г. 19:07
#hard
Задача: 188. Best Time to Buy and Sell Stock IV

Дан массив целых чисел prices, где prices[i] - это цена данной акции в i-й день, и целое число k.

Найдите максимальную прибыль, которую вы можете получить. Вы можете завершить не более чем k транзакций, т.е. вы можете купить не более k раз и продать не более k раз.

Обратите внимание: Вы не можете участвовать в нескольких транзакциях одновременно (т.е., вы должны продать акцию, прежде чем снова купить).

Пример:
Input: k = 2, prices = [2,4,1]
Output: 2
Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.


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

1️⃣Инициализация DP массива: Инициализируйте трехмерный массив dp, где dp[i][j][l] представляет максимальную прибыль на конец i-го дня с j оставшимися транзакциями и l акциями в портфеле. Начните с dp[0][0][0] = 0 (нет прибыли без акций и транзакций) и dp[0][1][1] = -prices[0] (покупка первой акции).

2️⃣Вычисление переходов: Для каждого дня и каждого возможного количества транзакций вычислите возможные действия: держать акцию, не держать акцию, купить акцию, если j > 0, или продать акцию. Обновляйте dp с использованием:
dp[i][j][1] = max(dp[i−1][j][1], dp[i−1][j−1][0] - prices[i]) (максимум между удержанием акции и покупкой новой).
dp[i][j][0] = max(dp[i−1][j][0], dp[i−1][j][1] + prices[i]) (максимум между неудержанием акции и продажей).

3️⃣Расчет результатов: По завершении всех дней, возвращайте максимальное значение dp[n-1][j][0] для всех j от 0 до k, что представляет максимальную прибыль без удержания акций на последний день. Обработайте специальный случай, когда 𝑘×2≥𝑛, чтобы избежать лишних расчетов.

😎 Решение:
public class Solution {
public int maxProfit(int k, int[] prices) {
int n = prices.length;

if (n <= 0 || k <= 0) {
return 0;
}

if (k * 2 >= n) {
int res = 0;
for (int i = 1; i < n; i++) {
res += Math.max(0, prices[i] - prices[i - 1]);
}
return res;
}
int[][][] dp = new int[n][k + 1][2];
for (int i = 0; i < n; i++) {
for (int j = 0; j <= k; j++) {
dp[i][j][0] = -1000000000;
dp[i][j][1] = -1000000000;
}
}
dp[0][0][0] = 0;
dp[0][1][1] = -prices[0];

for (int i = 1; i < n; i++) {
for (int j = 0; j <= k; j++) { dp[i][j][0] = Math.max(
dp[i - 1][j][0],
dp[i - 1][j][1] + prices[i]
);
if (j > 0) {
dp[i][j][1] = Math.max(
dp[i - 1][j][1],
dp[i - 1][j - 1][0] - prices[i]
);
}
}
}

int res = 0;
for (int j = 0; j <= k; j++) {
res = Math.max(res, dp[n - 1][j][0]);
}

return res;
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
31 августа 2024 г. 12:07
#medium
Задача: 187. Repeated DNA Sequences

ДНК состоит из серии нуклеотидов, обозначаемых как 'A', 'C', 'G' и 'T'.

Например, "ACGAATTCCG" — это последовательность ДНК.
При изучении ДНК полезно определять повторяющиеся последовательности внутри молекулы ДНК.

Дана строка s, представляющая последовательность ДНК. Верните все последовательности длиной 10 букв (подстроки), которые встречаются более одного раза в молекуле ДНК. Ответ можно возвращать в любом порядке.

Пример:
Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
Output: ["AAAAACCCCC","CCCCCAAAAA"]


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

1️⃣Перебираем начальные позиции последовательности от 1 до 𝑁−𝐿, где 𝑁 — длина строки, а 𝐿 — длина подстроки (в данном случае 10):
Если начальная позиция 𝑠𝑡𝑎𝑟𝑡==0, вычисляем хеш первой последовательности 𝑠[0:𝐿].
В противном случае вычисляем скользящий хеш из предыдущего значения хеша.

2️⃣Проверяем хеш в хешсете:
Если хеш уже существует в хешсете, значит, мы нашли повторяющуюся последовательность, и пора обновить вывод.
В противном случае добавляем хеш в хешсет.

3️⃣Возвращаем список вывода, содержащий все повторяющиеся последовательности.

😎 Решение:
class Solution {
public List findRepeatedDnaSequences(String s) {
int L = 10, n = s.length();
if (n <= L) return new ArrayList();
int a = 4, aL = (int) Math.pow(a, L);
Map toInt = new HashMap() {
{
put('A', 0);
put('C', 1);
put('G', 2);
put('T', 3);
}
};
int[] nums = new int[n];
for (int i = 0; i < n; ++i) nums[i] = toInt.get(s.charAt(i));

int h = 0;
Set seen = new HashSet();
Set output = new HashSet();
for (int start = 0; start < n - L + 1; ++start) {
if (start != 0) h = h * a -
nums[start - 1] * aL +
nums[start + L - 1];
else for (int i = 0; i < L; ++i) h = h * a + nums[i];
if (seen.contains(h)) output.add(s.substring(start, start + L));
seen.add(h);
}
return new ArrayList(output);
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых
Java | LeetCode
30 августа 2024 г. 19:07
#medium
Задача: 186. Reverse Words in a String II

Дан массив символов s, переверните порядок слов.

Слово определяется как последовательность символов, не являющихся пробелами. Слова в s будут разделены одним пробелом.

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

Пример:
Input: s = ["a"]
Output: ["a"]


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

1️⃣Перевернуть всю строку: применить функцию reverse, которая переворачивает весь массив символов от начала до конца.

2️⃣Перевернуть каждое слово: пройти по всей строке, идентифицировать границы каждого слова и использовать функцию reverse для переворачивания символов в пределах каждого слова.

3️⃣Окончательная корректировка: проверить, чтобы между словами оставался только один пробел, и удалить лишние пробелы в начале и конце строки, если это необходимо.

😎 Решение:
class Solution {
public void reverse(char[] s, int left, int right) {
while (left < right) {
char tmp = s[left];
s[left++] = s[right];
s[right--] = tmp;
}
}

public void reverseEachWord(char[] s) {
int n = s.length;
int start = 0, end = 0;

while (start < n) {
while (end < n && s[end] != ' ') ++end;
reverse(s, start, end - 1); start = end + 1;
++end;
}
}

public void reverseWords(char[] s) {
reverse(s, 0, s.length - 1);
reverseEachWord(s);
}
}


🔥 ТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесовБаза собесов | 🔒 База тестовыхБаза тестовых