#medium
Задача: 341. Flatten Nested List Iterator
Вам дан вложенный список целых чисел nestedList. Каждый элемент либо является целым числом, либо списком, элементы которого также могут быть целыми числами или другими списками. Реализуйте итератор для его развёртки.
Реализуйте класс NestedIterator:
NestedIterator(List<NestedInteger> nestedList) Инициализирует итератор вложенным списком nestedList.
int next() Возвращает следующий целый элемент вложенного списка.
boolean hasNext() Возвращает true, если в вложенном списке еще остались целые числа, и false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Сохраняйте исходный вложенный список в стеке или очереди. Используйте стек для сохранения состояния итерации по вложенным спискам.
2⃣ Метод next()
Возвращает следующий целый элемент из стека или очереди. Если текущий элемент является списком, развёртывайте его и добавляйте элементы в стек.
3⃣ Метод hasNext()
Проверяет, есть ли в стеке или очереди оставшиеся целые элементы. Если на вершине стека находится список, развёртывайте его до тех пор, пока не встретится целый элемент.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 341. Flatten Nested List Iterator
Вам дан вложенный список целых чисел nestedList. Каждый элемент либо является целым числом, либо списком, элементы которого также могут быть целыми числами или другими списками. Реализуйте итератор для его развёртки.
Реализуйте класс NestedIterator:
NestedIterator(List<NestedInteger> nestedList) Инициализирует итератор вложенным списком nestedList.
int next() Возвращает следующий целый элемент вложенного списка.
boolean hasNext() Возвращает true, если в вложенном списке еще остались целые числа, и false в противном случае.
Пример:
Input: nestedList = [[1,1],2,[1,1]]
Output: [1,1,2,1,1]
Explanation: By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].
Сохраняйте исходный вложенный список в стеке или очереди. Используйте стек для сохранения состояния итерации по вложенным спискам.
Возвращает следующий целый элемент из стека или очереди. Если текущий элемент является списком, развёртывайте его и добавляйте элементы в стек.
Проверяет, есть ли в стеке или очереди оставшиеся целые элементы. Если на вершине стека находится список, развёртывайте его до тех пор, пока не встретится целый элемент.
public class NestedIterator implements Iterator<Integer> {
private Stack<NestedInteger> stack;
public NestedIterator(List<NestedInteger> nestedList) {
stack = new Stack<>();
flatten(nestedList);
}
private void flatten(List<NestedInteger> nestedList) {
for (int i = nestedList.size() - 1; i >= 0; i--) {
stack.push(nestedList.get(i));
}
}
@Override
public Integer next() {
return stack.pop().getInteger();
}
@Override
public boolean hasNext() {
while (!stack.isEmpty() && !stack.peek().isInteger()) {
flatten(stack.pop().getList());
}
return !stack.isEmpty();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 726. Number of Atoms
Если задана строковая формула, представляющая химическую формулу, верните количество атомов. Атомный элемент всегда начинается с прописного символа, затем ноль или более строчных букв, представляющих его название. Если количество больше 1, за ним может следовать одна или более цифр, представляющих количество элементов. Например, "H2O" и "H2O2" возможны, а "H1O2" невозможен. Две формулы объединяются вместе, чтобы получить другую формулу. Например, "H2O2He3Mg4" также является формулой.
Формула, заключенная в круглые скобки, и счет (по желанию) также являются формулами. Например, "(H2O2)" и "(H2O2)3" являются формулами.
Возвращает количество всех элементов в виде строки в следующем виде: первое имя (в отсортированном порядке), затем его количество (если это количество больше 1), затем второе имя (в отсортированном порядке), затем его количество (если это количество больше 1) и т. д. Тестовые примеры генерируются таким образом, чтобы все значения в выводе помещались в 32-битное целое число.
Пример:
👨💻 Алгоритм:
1⃣ Используйте стек для отслеживания текущего уровня скобок.
2⃣ Пройдите по строке формулы, анализируя каждый символ: Если символ - это открывающая скобка '(', создайте новый словарь для хранения атомов внутри скобок. Если символ - это закрывающая скобка ')', извлеките словарь из стека и умножьте количества атомов на последующее число, если оно присутствует. Если символ - это атом (начинается с заглавной буквы), извлеките имя атома и его количество, и добавьте его в текущий словарь.
3⃣ После завершения обработки строки, объедините все словари из стека и отсортируйте результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 726. Number of Atoms
Если задана строковая формула, представляющая химическую формулу, верните количество атомов. Атомный элемент всегда начинается с прописного символа, затем ноль или более строчных букв, представляющих его название. Если количество больше 1, за ним может следовать одна или более цифр, представляющих количество элементов. Например, "H2O" и "H2O2" возможны, а "H1O2" невозможен. Две формулы объединяются вместе, чтобы получить другую формулу. Например, "H2O2He3Mg4" также является формулой.
Формула, заключенная в круглые скобки, и счет (по желанию) также являются формулами. Например, "(H2O2)" и "(H2O2)3" являются формулами.
Возвращает количество всех элементов в виде строки в следующем виде: первое имя (в отсортированном порядке), затем его количество (если это количество больше 1), затем второе имя (в отсортированном порядке), затем его количество (если это количество больше 1) и т. д. Тестовые примеры генерируются таким образом, чтобы все значения в выводе помещались в 32-битное целое число.
Пример:
Input: formula = "H2O"
Output: "H2O"
import java.util.*;
public class Solution {
public String countOfAtoms(String formula) {
Stack<Map<String, Integer>> stack = new Stack<>();
stack.push(new HashMap<>());
int n = formula.length();
int i = 0;
while (i < n) {
if (formula.charAt(i) == '(') {
stack.push(new HashMap<>());
i++;
} else if (formula.charAt(i) == ')') {
Map<String, Integer> top = stack.pop();
i++;
int start = i;
while (i < n && Character.isDigit(formula.charAt(i))) {
i++;
}
int multiplicity = i > start ? Integer.parseInt(formula.substring(start, i)) : 1;
for (String name : top.keySet()) {
int count = top.get(name);
stack.peek().put(name, stack.peek().getOrDefault(name, 0) + count * multiplicity);
}
} else {
int start = i;
i++;
while (i < n && Character.isLowerCase(formula.charAt(i))) {
i++;
}
String name = formula.substring(start, i);
start = i;
while (i < n && Character.isDigit(formula.charAt(i))) {
i++;
}
int multiplicity = i > start ? Integer.parseInt(formula.substring(start, i)) : 1;
stack.peek().put(name, stack.peek().getOrDefault(name, 0) + multiplicity);
}
}
Map<String, Integer> countMap = stack.pop();
StringBuilder sb = new StringBuilder();
for (String name : new TreeMap<>(countMap).keySet()) {
sb.append(name);
int count = countMap.get(name);
if (count > 1) {
sb.append(count);
}
}
return sb.toString();
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1💊1
#hard
Задача: 727. Minimum Window Subsequence
Если в строках s1 и s2 нет такого окна, которое покрывало бы все символы в s2, верните пустую строку "". Если таких окон минимальной длины несколько, возвращается окно с самым левым начальным индексом.
Пример:
👨💻 Алгоритм:
1⃣ Используйте два указателя для определения текущего окна.
2⃣ Поддерживайте счетчики для символов в текущем окне и требуемых символов из s2.
3⃣ Перемещайте правый указатель, чтобы найти подходящее окно, и левый указатель, чтобы минимизировать его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 727. Minimum Window Subsequence
Если в строках s1 и s2 нет такого окна, которое покрывало бы все символы в s2, верните пустую строку "". Если таких окон минимальной длины несколько, возвращается окно с самым левым начальным индексом.
Пример:
Input: s1 = "abcdebdde", s2 = "bde"
Output: "bcde"
import java.util.HashMap;
import java.util.Map;
public class Solution {
public String minWindow(String s1, String s2) {
if (s1.isEmpty() || s2.isEmpty()) {
return "";
}
Map<Character, Integer> dictT = new HashMap<>();
for (char c : s2.toCharArray()) {
dictT.put(c, dictT.getOrDefault(c, 0) + 1);
}
int required = dictT.size();
int l = 0, r = 0, formed = 0;
Map<Character, Integer> windowCounts = new HashMap<>();
int[] ans = {Integer.MAX_VALUE, 0, 0};
while (r < s1.length()) {
char c = s1.charAt(r);
windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1);
if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT.get(c).intValue()) {
formed++;
}
while (l <= r && formed == required) {
c = s1.charAt(l);
if (r - l + 1 < ans[0]) {
ans[0] = r - l + 1;
ans[1] = l;
ans[2] = r;
}
windowCounts.put(c, windowCounts.get(c) - 1);
if (dictT.containsKey(c) && windowCounts.get(c).intValue() < dictT.get(c).intValue()) {
formed--;
}
l++;
}
r++;
}
return ans[0] == Integer.MAX_VALUE ? "" : s1.substring(ans[1], ans[2] + 1);
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 728. Self Dividing Numbers
Например, 128 является саморазделяющимся числом, потому что 128 % 1 == 0, 128 % 2 == 0 и 128 % 8 == 0. Саморазделяющееся число не может содержать цифру ноль. Если даны два целых числа left и right, верните список всех саморазделяющихся чисел в диапазоне [left, right].
Пример:
👨💻 Алгоритм:
1⃣ Переберите все числа в диапазоне от left до right.
2⃣ Для каждого числа проверьте, является ли оно саморазделяющимся: Разделите число на его цифры. Убедитесь, что ни одна цифра не равна нулю и число делится на каждую из своих цифр без остатка.
3⃣ Добавьте саморазделяющиеся числа в результативный список и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 728. Self Dividing Numbers
Например, 128 является саморазделяющимся числом, потому что 128 % 1 == 0, 128 % 2 == 0 и 128 % 8 == 0. Саморазделяющееся число не может содержать цифру ноль. Если даны два целых числа left и right, верните список всех саморазделяющихся чисел в диапазоне [left, right].
Пример:
Input: left = 1, right = 22
Output: [1,2,3,4,5,6,7,8,9,11,12,15,22]
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer> result = new ArrayList<>();
for (int num = left; num <= right; num++) {
if (isSelfDividing(num)) {
result.add(num);
}
}
return result;
}
private boolean isSelfDividing(int num) {
int n = num;
while (n > 0) {
int digit = n % 10;
if (digit == 0 || num % digit != 0) {
return false;
}
n /= 10;
}
return true;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
#medium
Задача: 729. My Calendar I
Вы создаете программу для использования в качестве календаря. Мы можем добавить новое событие, если его добавление не приведет к двойному бронированию. Двойное бронирование происходит, когда два события имеют некоторое непустое пересечение (т.е, Событие можно представить в виде пары целых чисел start и end, которая представляет собой бронирование на полуоткрытом интервале [start, end), диапазоне вещественных чисел x таких, что start <= x < end. Реализация класса MyCalendar: MyCalendar() Инициализирует объект календаря. boolean book(int start, int end) Возвращает true, если событие может быть успешно добавлено в календарь, не вызывая двойного бронирования. В противном случае возвращается false и событие не добавляется в календарь.
Пример:
👨💻 Алгоритм:
1⃣ Создайте класс MyCalendar с инициализатором для хранения списка событий.
2⃣ Реализуйте метод book(int start, int end) для проверки пересечения нового события с уже существующими событиями.
3⃣ Если новое событие не пересекается с существующими событиями, добавьте его в список событий и верните true. В противном случае верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 729. My Calendar I
Вы создаете программу для использования в качестве календаря. Мы можем добавить новое событие, если его добавление не приведет к двойному бронированию. Двойное бронирование происходит, когда два события имеют некоторое непустое пересечение (т.е, Событие можно представить в виде пары целых чисел start и end, которая представляет собой бронирование на полуоткрытом интервале [start, end), диапазоне вещественных чисел x таких, что start <= x < end. Реализация класса MyCalendar: MyCalendar() Инициализирует объект календаря. boolean book(int start, int end) Возвращает true, если событие может быть успешно добавлено в календарь, не вызывая двойного бронирования. В противном случае возвращается false и событие не добавляется в календарь.
Пример:
Input
["MyCalendar", "book", "book", "book"]
[[], [10, 20], [15, 25], [20, 30]]
Output
[null, true, false, true]
import java.util.ArrayList;
import java.util.List;
public class MyCalendar {
private List<int[]> events;
public MyCalendar() {
events = new ArrayList<>();
}
public boolean book(int start, int end) {
for (int[] event : events) {
if (start < event[1] && end > event[0]) {
return false;
}
}
events.add(new int[] {start, end});
return true;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 730. Count Different Palindromic Subsequences
Поскольку ответ может быть очень большим, верните его по модулю 109 + 7. Подпоследовательность строки получается путем удаления из нее нуля или более символов. Последовательность является палиндромной, если она равна последовательности, обращенной назад. Две последовательности a1, a2, ... и b1, b2, ... различны, если существует некоторое i, для которого ai != bi.
Пример:
👨💻 Алгоритм:
1⃣ Используйте динамическое программирование для подсчета количества палиндромных подпоследовательностей.
2⃣ Введите двумерный массив dp, где dp[i][j] представляет количество палиндромных подпоследовательностей в подстроке от i до j.
3⃣ Итерируйте по длине подстрок от 1 до длины строки и обновляйте значения в dp на основе состояния предыдущих подстрок.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 730. Count Different Palindromic Subsequences
Поскольку ответ может быть очень большим, верните его по модулю 109 + 7. Подпоследовательность строки получается путем удаления из нее нуля или более символов. Последовательность является палиндромной, если она равна последовательности, обращенной назад. Две последовательности a1, a2, ... и b1, b2, ... различны, если существует некоторое i, для которого ai != bi.
Пример:
Input: s = "bccb"
Output: 6
public class Solution {
public int countPalindromicSubsequences(String s) {
int MOD = 1000000007;
int n = s.length();
int[][] dp = new int[n][n];
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
}
for (int length = 2; length <= n; length++) {
for (int i = 0; i <= n - length; i++) {
int j = i + length - 1;
if (s.charAt(i) == s.charAt(j)) {
int l = i + 1, r = j - 1;
while (l <= r && s.charAt(l) != s.charAt(i)) l++;
while (l <= r && s.charAt(r) != s.charAt(j)) r--;
if (l > r) {
dp[i][j] = dp[i + 1][j - 1] * 2 + 2;
} else if (l == r) {
dp[i][j] = dp[i + 1][j - 1] * 2 + 1;
} else {
dp[i][j] = dp[i + 1][j - 1] * 2 - dp[l + 1][r - 1];
}
} else {
dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1];
}
dp[i][j] = (dp[i][j] + MOD) % MOD;
}
}
return dp[0][n - 1];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 731. My Calendar II
Вы создаете программу для использования в качестве календаря. Мы можем добавить новое событие, если его добавление не приведет к тройному бронированию. Тройное бронирование происходит, когда три события имеют некоторое непустое пересечение (т.е, Событие можно представить в виде пары целых чисел start и end, которая представляет собой бронирование на полуоткрытом интервале [start, end), диапазоне вещественных чисел x таких, что start <= x < end. Реализация класса MyCalendarTwo: MyCalendarTwo() Инициализирует объект календаря. boolean book(int start, int end) Возвращает true, если событие может быть успешно добавлено в календарь, не вызывая тройного бронирования. В противном случае возвращается false и событие не добавляется в календарь.
Пример:
👨💻 Алгоритм:
1⃣ Создайте два списка: один для отслеживания всех событий, второй для отслеживания пересечений. подпоследовательностей.
2⃣ При добавлении нового события сначала проверьте, не пересекается ли оно с любыми существующими пересечениями.
3⃣ Если пересечение не обнаружено, добавьте новое событие и обновите список пересечений при необходимости.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 731. My Calendar II
Вы создаете программу для использования в качестве календаря. Мы можем добавить новое событие, если его добавление не приведет к тройному бронированию. Тройное бронирование происходит, когда три события имеют некоторое непустое пересечение (т.е, Событие можно представить в виде пары целых чисел start и end, которая представляет собой бронирование на полуоткрытом интервале [start, end), диапазоне вещественных чисел x таких, что start <= x < end. Реализация класса MyCalendarTwo: MyCalendarTwo() Инициализирует объект календаря. boolean book(int start, int end) Возвращает true, если событие может быть успешно добавлено в календарь, не вызывая тройного бронирования. В противном случае возвращается false и событие не добавляется в календарь.
Пример:
Input
["MyCalendarTwo", "book", "book", "book", "book", "book", "book"]
[[], [10, 20], [50, 60], [10, 40], [5, 15], [5, 10], [25, 55]]
Output
[null, true, true, true, false, true, true]
import java.util.ArrayList;
import java.util.List;
public class MyCalendarTwo {
private List<int[]> events;
private List<int[]> overlaps;
public MyCalendarTwo() {
events = new ArrayList<>();
overlaps = new ArrayList<>();
}
public boolean book(int start, int end) {
for (int[] overlap : overlaps) {
if (start < overlap[1] && end > overlap[0]) {
return false;
}
}
for (int[] event : events) {
if (start < event[1] && end > event[0]) {
overlaps.add(new int[]{Math.max(start, event[0]), Math.min(end, event[1])});
}
}
events.add(new int[]{start, end});
return true;
}
} this.events.push([start, end]);
return true;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 732. My Calendar III
k-бронирование происходит, когда k событий имеют некоторое непустое пересечение (т.е, дано некоторое время, общее для всех k событий). Даны некоторые события [startTime, endTime), после каждого данного события верните целое число k, представляющее максимальное k-бронирование между всеми предыдущими событиями. Реализация класса MyCalendarThree: MyCalendarThree() Инициализирует объект. int book(int startTime, int endTime) Возвращает целое число k, представляющее наибольшее целое число, при котором в календаре существует k-бронирование.
Пример:
👨💻 Алгоритм:
1⃣ Создайте два словаря для хранения изменений времени бронирования: один для начала событий, другой для конца событий.
2⃣ Для каждого нового события обновите словари начала и конца событий.
3⃣ Поддерживайте текущее количество активных бронирований и обновляйте максимальное количество активных бронирований по мере добавления новых событий.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 732. My Calendar III
k-бронирование происходит, когда k событий имеют некоторое непустое пересечение (т.е, дано некоторое время, общее для всех k событий). Даны некоторые события [startTime, endTime), после каждого данного события верните целое число k, представляющее максимальное k-бронирование между всеми предыдущими событиями. Реализация класса MyCalendarThree: MyCalendarThree() Инициализирует объект. int book(int startTime, int endTime) Возвращает целое число k, представляющее наибольшее целое число, при котором в календаре существует k-бронирование.
Пример:
Input
["MyCalendarThree", "book", "book", "book", "book", "book", "book"]
[[], [10, 20], [50, 60], [10, 40], [5, 15], [5, 10], [25, 55]]
Output
[null, 1, 1, 2, 3, 3, 3]
import java.util.Map;
import java.util.TreeMap;
public class MyCalendarThree {
private TreeMap<Integer, Integer> events;
public MyCalendarThree() {
events = new TreeMap<>();
}
public int book(int startTime, int endTime) {
events.put(startTime, events.getOrDefault(startTime, 0) + 1);
events.put(endTime, events.getOrDefault(endTime, 0) - 1);
int active = 0;
int maxActive = 0;
for (Map.Entry<Integer, Integer> entry : events.entrySet()) {
active += entry.getValue();
maxActive = Math.max(maxActive, active);
}
return maxActive;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#easy
Задача: 733. Flood Fill
Изображение представлено в виде целочисленной сетки m x n, где image[i][j] - значение пикселя изображения. Вам также даны три целых числа sr, sc и color. Вы должны выполнить заливку изображения, начиная с пикселя image[sr][sc]. Чтобы выполнить заливку, рассмотрите начальный пиксель, плюс все пиксели, соединенные по 4-м направлениям с начальным пикселем, того же цвета, что и начальный пиксель, плюс все пиксели, соединенные по 4-м направлениям с этими пикселями (также того же цвета), и так далее. Замените цвет всех вышеупомянутых пикселей на цвет. Верните измененное изображение после выполнения заливки.
Пример:
👨💻 Алгоритм:
1⃣ Получите цвет начального пикселя.
2⃣ Используйте обход в глубину (DFS) или обход в ширину (BFS) для замены цвета всех пикселей, которые соединены с начальным пикселем и имеют тот же цвет.
3⃣ Обновите изображение и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 733. Flood Fill
Изображение представлено в виде целочисленной сетки m x n, где image[i][j] - значение пикселя изображения. Вам также даны три целых числа sr, sc и color. Вы должны выполнить заливку изображения, начиная с пикселя image[sr][sc]. Чтобы выполнить заливку, рассмотрите начальный пиксель, плюс все пиксели, соединенные по 4-м направлениям с начальным пикселем, того же цвета, что и начальный пиксель, плюс все пиксели, соединенные по 4-м направлениям с этими пикселями (также того же цвета), и так далее. Замените цвет всех вышеупомянутых пикселей на цвет. Верните измененное изображение после выполнения заливки.
Пример:
Input: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2
Output: [[2,2,2],[2,2,0],[2,0,1]]
public class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
int originalColor = image[sr][sc];
if (originalColor == color) {
return image;
}
dfs(image, sr, sc, originalColor, color);
return image;
}
private void dfs(int[][] image, int x, int y, int originalColor, int newColor) {
if (x < 0 || x >= image.length || y < 0 || y >= image[0].length || image[x][y] != originalColor) {
return;
}
image[x][y] = newColor;
dfs(image, x + 1, y, originalColor, newColor);
dfs(image, x - 1, y, originalColor, newColor);
dfs(image, x, y + 1, originalColor, newColor);
dfs(image, x, y - 1, originalColor, newColor);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#easy
Задача: 734. Sentence Similarity
Мы можем представить предложение в виде массива слов, например, предложение "I am happy with leetcode" можно представить как arr = ["I", "am",happy", "with", "leetcode"].
Даны два предложения sentence1 и sentence2, каждое из которых представлено в виде массива строк, и массив пар строк similarPairs, где similarPairs[i] = [xi, yi] указывает, что два слова xi и yi похожи. Возвращается true, если предложения sentence1 и sentence2 похожи, или false, если они не похожи. Два предложения похожи, если: у них одинаковая длина (т.е, Заметьте, что слово всегда похоже само на себя, также обратите внимание, что отношение сходства не является транзитивным. Например, если слова a и b похожи, а слова b и c похожи, то a и c не обязательно похожи.
Пример:
👨💻 Алгоритм:
1⃣ Проверьте, равны ли длины предложений sentence1 и sentence2. Если нет, верните false.
2⃣ Создайте словарь для хранения всех пар похожих слов.
3⃣ Проверьте каждую пару слов из предложений sentence1 и sentence2 на схожесть, используя словарь и правило, что слово всегда похоже на само себя.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 734. Sentence Similarity
Мы можем представить предложение в виде массива слов, например, предложение "I am happy with leetcode" можно представить как arr = ["I", "am",happy", "with", "leetcode"].
Даны два предложения sentence1 и sentence2, каждое из которых представлено в виде массива строк, и массив пар строк similarPairs, где similarPairs[i] = [xi, yi] указывает, что два слова xi и yi похожи. Возвращается true, если предложения sentence1 и sentence2 похожи, или false, если они не похожи. Два предложения похожи, если: у них одинаковая длина (т.е, Заметьте, что слово всегда похоже само на себя, также обратите внимание, что отношение сходства не является транзитивным. Например, если слова a и b похожи, а слова b и c похожи, то a и c не обязательно похожи.
Пример:
Input: sentence1 = ["great","acting","skills"], sentence2 = ["fine","drama","talent"], similarPairs = [["great","fine"],["drama","acting"],["skills","talent"]]
Output: true
import java.util.*;
public class Solution {
public boolean areSentencesSimilar(String[] sentence1, String[] sentence2, List<List<String>> similarPairs) {
if (sentence1.length != sentence2.length) {
return false;
}
Map<String, Set<String>> similar = new HashMap<>();
for (List<String> pair : similarPairs) {
String x = pair.get(0);
String y = pair.get(1);
similar.computeIfAbsent(x, k -> new HashSet<>()).add(y);
similar.computeIfAbsent(y, k -> new HashSet<>()).add(x);
}
for (int i = 0; i < sentence1.length; i++) {
String w1 = sentence1[i];
String w2 = sentence2[i];
if (!w1.equals(w2) && (!similar.containsKey(w1) || !similar.get(w1).contains(w2))) {
return false;
}
}
return true;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 735. Asteroid Collision
Нам дан массив asteroids, состоящий из целых чисел, представляющих астероиды в ряд. Для каждого астероида абсолютное значение обозначает его размер, а знак - направление движения (положительное - вправо, отрицательное - влево). Каждый астероид движется с одинаковой скоростью. Определите состояние астероидов после всех столкновений. Если два астероида столкнутся, меньший из них взорвется. Если оба одинакового размера, то взорвутся оба. Два астероида, движущиеся в одном направлении, никогда не встретятся.
Пример:
👨💻 Алгоритм:
1⃣ Используйте стек для отслеживания движущихся вправо астероидов.
2⃣ Пройдите по массиву астероидов: Если астероид движется вправо, добавьте его в стек. Если астероид движется влево, сравните его с последним астероидом в стеке (если он есть и движется вправо): Если движущийся вправо астероид больше, текущий взорвется. Если движущийся влево астероид больше, последний астероид в стеке взорвется, и продолжите сравнение. Если они одинакового размера, оба взорвутся.
3⃣ Добавьте оставшиеся астероиды из стека и текущий астероид в результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 735. Asteroid Collision
Нам дан массив asteroids, состоящий из целых чисел, представляющих астероиды в ряд. Для каждого астероида абсолютное значение обозначает его размер, а знак - направление движения (положительное - вправо, отрицательное - влево). Каждый астероид движется с одинаковой скоростью. Определите состояние астероидов после всех столкновений. Если два астероида столкнутся, меньший из них взорвется. Если оба одинакового размера, то взорвутся оба. Два астероида, движущиеся в одном направлении, никогда не встретятся.
Пример:
Input: sentence1 = ["great","acting","skills"], sentence2 = ["fine","drama","talent"], similarPairs = [["great","fine"],["drama","acting"],["skills","talent"]]
Output: true
import java.util.*;
public class Solution {
public int[] asteroidCollision(int[] asteroids) {
Stack<Integer> stack = new Stack<>();
for (int asteroid : asteroids) {
boolean alive = true;
while (alive && asteroid < 0 && !stack.isEmpty() && stack.peek() > 0) {
int last = stack.pop();
if (last == -asteroid) {
alive = false;
} else if (last > -asteroid) {
stack.push(last);
alive = false;
}
}
if (alive) {
stack.push(asteroid);
}
}
int[] result = new int[stack.size()];
for (int i = result.length - 1; i >= 0; i--) {
result[i] = stack.pop();
}
return result;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 736. Parse Lisp Expression
Нам дан массив asteroids, состоящий из целых чисел, представляющих астероиды в ряд. Для каждого астероида абсолютное значение обозначает его размер, а знак - направление движения (положительное - вправо, отрицательное - влево). Каждый астероид движется с одинаковой скоростью. Определите состояние астероидов после всех столкновений. Если два астероида столкнутся, меньший из них взорвется. Если оба одинакового размера, то взорвутся оба. Два астероида, движущиеся в одном направлении, никогда не встретятся.
Пример:
👨💻 Алгоритм:
1⃣ Определите функцию для оценки выражений.
2⃣ Используйте рекурсивный подход для обработки различных типов выражений (let, add, mult, и переменных).
3⃣ Используйте словарь для отслеживания значений переменных с учетом области видимости.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 736. Parse Lisp Expression
Нам дан массив asteroids, состоящий из целых чисел, представляющих астероиды в ряд. Для каждого астероида абсолютное значение обозначает его размер, а знак - направление движения (положительное - вправо, отрицательное - влево). Каждый астероид движется с одинаковой скоростью. Определите состояние астероидов после всех столкновений. Если два астероида столкнутся, меньший из них взорвется. Если оба одинакового размера, то взорвутся оба. Два астероида, движущиеся в одном направлении, никогда не встретятся.
Пример:
Input: expression = "(let x 2 (mult x (let x 3 y 4 (add x y))))"
Output: 14
import java.util.*;
public class Solution {
public int evaluate(String expression) {
return evaluate(expression, new HashMap<>());
}
private int evaluate(String expression, Map<String, Integer> env) {
if (!expression.startsWith("(")) {
if (Character.isDigit(expression.charAt(0)) || expression.charAt(0) == '-') {
return Integer.parseInt(expression);
}
return env.get(expression);
}
List<String> tokens = tokenize(expression);
if (tokens.get(0).equals("let")) {
for (int i = 1; i < tokens.size() - 2; i += 2) {
env.put(tokens.get(i), evaluate(tokens.get(i + 1), env));
}
return evaluate(tokens.get(tokens.size() - 1), env);
} else if (tokens.get(0).equals("add")) {
return evaluate(tokens.get(1), env) + evaluate(tokens.get(2), env);
} else if (tokens.get(0).equals("mult")) {
return evaluate(tokens.get(1), env) * evaluate(tokens.get(2), env);
}
return 0;
}
private List<String> tokenize(String expression) {
List<String> tokens = new ArrayList<>();
StringBuilder token = new StringBuilder();
int parens = 0;
for (char c : expression.toCharArray()) {
if (c == '(') {
parens++;
if (parens == 1) continue;
} else if (c == ')') {
parens--;
if (parens == 0) {
tokens.addAll(tokenize(token.toString()));
token = new StringBuilder();
continue;
}
} else if (c == ' ' && parens == 1) {
if (token.length() > 0) {
tokens.add(token.toString());
token = new StringBuilder();
}
continue;
}
token.append(c);
}
if (token.length() > 0) {
tokens.add(token.toString());
}
return tokens;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 737. Sentence Similarity II
Мы можем представить предложение в виде массива слов, например, предложение "I am happy with leetcode" можно представить как arr = ["I", "am",happy", "with", "leetcode"].
Даны два предложения sentence1 и sentence2, каждое из которых представлено в виде массива строк, и массив пар строк similarPairs, где similarPairs[i] = [xi, yi] указывает, что два слова xi и yi похожи. Возвращается true, если предложения sentence1 и sentence2 похожи, или false, если они не похожи. Два предложения похожи, если: у них одинаковая длина (т.е, Заметьте, что слово всегда похоже само на себя, также обратите внимание, что отношение сходства является транзитивным. Например, если слова a и b похожи, а слова b и c похожи, то a и c похожи.
Пример:
👨💻 Алгоритм:
1⃣ Проверить, одинаковой ли длины предложения sentence1 и sentence2. Если нет, вернуть false.
2⃣ Построить граф схожести слов с использованием словаря.
3⃣ Использовать поиск в глубину (DFS) для проверки транзитивной схожести слов в предложениях.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 737. Sentence Similarity II
Мы можем представить предложение в виде массива слов, например, предложение "I am happy with leetcode" можно представить как arr = ["I", "am",happy", "with", "leetcode"].
Даны два предложения sentence1 и sentence2, каждое из которых представлено в виде массива строк, и массив пар строк similarPairs, где similarPairs[i] = [xi, yi] указывает, что два слова xi и yi похожи. Возвращается true, если предложения sentence1 и sentence2 похожи, или false, если они не похожи. Два предложения похожи, если: у них одинаковая длина (т.е, Заметьте, что слово всегда похоже само на себя, также обратите внимание, что отношение сходства является транзитивным. Например, если слова a и b похожи, а слова b и c похожи, то a и c похожи.
Пример:
Input: sentence1 = ["great","acting","skills"], sentence2 = ["fine","drama","talent"], similarPairs = [["great","good"],["fine","good"],["drama","acting"],["skills","talent"]]
Output: true
import java.util.*;
public class Solution {
public boolean areSentencesSimilar(String[] sentence1, String[] sentence2, List<List<String>> similarPairs) {
if (sentence1.length != sentence2.length) {
return false;
}
Map<String, List<String>> graph = new HashMap<>();
for (List<String> pair : similarPairs) {
graph.computeIfAbsent(pair.get(0), k -> new ArrayList<>()).add(pair.get(1));
graph.computeIfAbsent(pair.get(1), k -> new ArrayList<>()).add(pair.get(0));
}
for (int i = 0; i < sentence1.length; i++) {
if (!sentence1[i].equals(sentence2[i]) && !dfs(sentence1[i], sentence2[i], graph, new HashSet<>())) {
return false;
}
}
return true;
}
private boolean dfs(String word1, String word2, Map<String, List<String>> graph, Set<String> visited) {
if (word1.equals(word2)) {
return true;
}
visited.add(word1);
for (String neighbor : graph.getOrDefault(word1, Collections.emptyList())) {
if (!visited.contains(neighbor) && dfs(neighbor, word2, graph, visited)) {
return true;
}
}
return false;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 738. Monotone Increasing Digits
Целое число имеет монотонно возрастающие цифры тогда и только тогда, когда каждая пара соседних цифр x и y удовлетворяет x <= y. Задав целое число n, верните наибольшее число, которое меньше или равно n с монотонно возрастающими цифрами.
Пример:
👨💻 Алгоритм:
1⃣ Преобразуйте число в строку для удобства обработки.
2⃣ Найдите позицию, где последовательность перестает быть монотонной.
3⃣ Уменьшите соответствующую цифру и установите все последующие цифры в 9.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 738. Monotone Increasing Digits
Целое число имеет монотонно возрастающие цифры тогда и только тогда, когда каждая пара соседних цифр x и y удовлетворяет x <= y. Задав целое число n, верните наибольшее число, которое меньше или равно n с монотонно возрастающими цифрами.
Пример:
Input: n = 10
Output: 9
public class Solution {
public int monotoneIncreasingDigits(int n) {
char[] digits = Integer.toString(n).toCharArray();
int mark = digits.length;
for (int i = digits.length - 1; i > 0; i--) {
if (digits[i] < digits[i - 1]) {
mark = i;
digits[i - 1]--;
}
}
for (int i = mark; i < digits.length; i++) {
digits[i] = '9';
}
return Integer.parseInt(new String(digits));
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
#medium
Задача: 739. Daily Temperatures
Задав массив целых чисел temperature, представляющих дневные температуры, верните массив answer, такой, что answer[i] - это количество дней, которые нужно подождать после i-го дня, чтобы температура стала теплее. Если в будущем не существует дня, для которого это возможно, сохраните answer[i] == 0.
Пример:
👨💻 Алгоритм:
1⃣ Создайте стек для хранения индексов дней с температурами, для которых еще не найден более теплый день.
2⃣ Пройдите по массиву температур и для каждого дня: Пока текущая температура больше температуры дня на вершине стека, обновляйте массив ответов и удаляйте вершину стека. Добавьте текущий день в стек.
3⃣ Возвращайте массив ответов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 739. Daily Temperatures
Задав массив целых чисел temperature, представляющих дневные температуры, верните массив answer, такой, что answer[i] - это количество дней, которые нужно подождать после i-го дня, чтобы температура стала теплее. Если в будущем не существует дня, для которого это возможно, сохраните answer[i] == 0.
Пример:
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]
public class Solution {
public int[] dailyTemperatures(int[] T) {
int n = T.length;
int[] answer = new int[n];
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && T[i] > T[stack.peek()]) {
int j = stack.pop();
answer[j] = i - j;
}
stack.push(i);
}
return answer;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
#medium
Задача: 740. Delete and Earn
Вам дан целочисленный массив nums. Вы хотите максимизировать количество очков, выполнив следующую операцию любое количество раз: Выберите любой элемент nums[i] и удалите его, чтобы заработать nums[i] очков. После этого вы должны удалить каждый элемент, равный nums[i] - 1, и каждый элемент, равный nums[i] + 1. Верните максимальное количество очков, которое вы можете заработать, применив вышеуказанную операцию некоторое количество раз.
Пример:
👨💻 Алгоритм:
1⃣ Подсчитайте количество каждого числа в массиве nums.
2⃣ Используйте динамическое программирование для расчета максимальных очков, которые можно заработать, используя накопленный результат для чисел, меньших текущего. Добавьте текущий день в стек.
3⃣ Для каждого числа num в nums, учитывайте два случая: не брать число или взять число и добавить его очки.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 740. Delete and Earn
Вам дан целочисленный массив nums. Вы хотите максимизировать количество очков, выполнив следующую операцию любое количество раз: Выберите любой элемент nums[i] и удалите его, чтобы заработать nums[i] очков. После этого вы должны удалить каждый элемент, равный nums[i] - 1, и каждый элемент, равный nums[i] + 1. Верните максимальное количество очков, которое вы можете заработать, применив вышеуказанную операцию некоторое количество раз.
Пример:
Input: nums = [3,4,2]
Output: 6
import java.util.*;
public class Solution {
public int deleteAndEarn(int[] nums) {
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
int avoid = 0, using = 0, prev = -1;
for (int num : count.keySet().stream().sorted().mapToInt(Integer::intValue).toArray()) {
if (num - 1 != prev) {
int newAvoid = Math.max(avoid, using);
using = num * count.get(num) + Math.max(avoid, using);
avoid = newAvoid;
} else {
int newAvoid = Math.max(avoid, using);
using = num * count.get(num) + avoid;
avoid = newAvoid;
}
prev = num;
}
return Math.max(avoid, using);
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 741. Cherry Pickup
Вам дана сетка n x n, представляющая поле вишен. Каждая клетка - одно из трех возможных целых чисел. 0 означает, что клетка пуста, и вы можете пройти через нее, 1 означает, что клетка содержит вишню, которую вы можете сорвать и пройти через нее, или -1 означает, что клетка содержит шип, который преграждает вам путь. Верните максимальное количество вишен, которое вы можете собрать, следуя следующим правилам: Начиная с позиции (0, 0) и достигая (n - 1, n - 1) путем перемещения вправо или вниз через допустимые клетки пути (клетки со значением 0 или 1).
После достижения (n - 1, n - 1) вернитесь в (0, 0), двигаясь влево или вверх по клеткам с действительными путями. Проходя через клетку пути, содержащую вишню, вы поднимаете ее, и клетка становится пустой клеткой 0. Если между (0, 0) и (n - 1, n - 1) нет действительного пути, то вишни собрать нельзя.
Пример:
👨💻 Алгоритм:
1⃣ Используйте динамическое программирование для подсчета максимального количества вишен, которые можно собрать при движении от (0, 0) до (n - 1, n - 1).
2⃣ Примените еще один проход с использованием динамического программирования для движения обратно от (n - 1, n - 1) до (0, 0), чтобы учитывать вишни, собранные на обратном пути.
3⃣ Объедините результаты двух проходов, чтобы найти максимальное количество вишен, которые можно собрать.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 741. Cherry Pickup
Вам дана сетка n x n, представляющая поле вишен. Каждая клетка - одно из трех возможных целых чисел. 0 означает, что клетка пуста, и вы можете пройти через нее, 1 означает, что клетка содержит вишню, которую вы можете сорвать и пройти через нее, или -1 означает, что клетка содержит шип, который преграждает вам путь. Верните максимальное количество вишен, которое вы можете собрать, следуя следующим правилам: Начиная с позиции (0, 0) и достигая (n - 1, n - 1) путем перемещения вправо или вниз через допустимые клетки пути (клетки со значением 0 или 1).
После достижения (n - 1, n - 1) вернитесь в (0, 0), двигаясь влево или вверх по клеткам с действительными путями. Проходя через клетку пути, содержащую вишню, вы поднимаете ее, и клетка становится пустой клеткой 0. Если между (0, 0) и (n - 1, n - 1) нет действительного пути, то вишни собрать нельзя.
Пример:
Input: grid = [[0,1,-1],[1,0,-1],[1,1,1]]
Output: 5
public class Solution {
public int cherryPickup(int[][] grid) {
int n = grid.length;
int[][][] dp = new int[n][n][2 * n - 1];
for (int[][] layer : dp) {
for (int[] row : layer) {
Arrays.fill(row, Integer.MIN_VALUE);
}
}
dp[0][0][0] = grid[0][0];
for (int k = 1; k < 2 * n - 1; k++) {
for (int i1 = Math.max(0, k - n + 1); i1 <= Math.min(n - 1, k); i1++) {
for (int i2 = Math.max(0, k - n + 1); i2 <= Math.min(n - 1, k); i2++) {
int j1 = k - i1, j2 = k - i2;
if (j1 < n && j2 < n && grid[i1][j1] != -1 && grid[i2][j2] != -1) {
int maxCherries = Integer.MIN_VALUE;
if (i1 > 0 && i2 > 0) maxCherries = Math.max(maxCherries, dp[i1 - 1][i2 - 1][k - 1]);
if (i1 > 0) maxCherries = Math.max(maxCherries, dp[i1 - 1][i2][k - 1]);
if (i2 > 0) maxCherries = Math.max(maxCherries, dp[i1][i2 - 1][k - 1]);
maxCherries = Math.max(maxCherries, dp[i1][i2][k - 1]);
if (maxCherries != Integer.MIN_VALUE) {
dp[i1][i2][k] = maxCherries + grid[i1][j1];
if (i1 != i2) dp[i1][i2][k] += grid[i2][j2];
}
}
}
}
}
return Math.max(0, dp[n - 1][n - 1][2 * (n - 1)]);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 742. Closest Leaf in a Binary Tree
Если задан корень бинарного дерева, в котором каждый узел имеет уникальное значение, а также задано целое число k, верните значение ближайшего к цели k узла листа дерева. Ближайший к листу узел означает наименьшее количество ребер, пройденных бинарным деревом, чтобы достичь любого листа дерева. Кроме того, узел называется листом, если у него нет дочерних узлов.
Пример:
👨💻 Алгоритм:
1⃣ Пройдите дерево, чтобы найти путь от корня до узла k и сохранить его в список.
2⃣ Найдите все листья и минимальное расстояние до них, используя BFS, начиная с найденного узла k.
3⃣ Верните значение ближайшего листа.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 742. Closest Leaf in a Binary Tree
Если задан корень бинарного дерева, в котором каждый узел имеет уникальное значение, а также задано целое число k, верните значение ближайшего к цели k узла листа дерева. Ближайший к листу узел означает наименьшее количество ребер, пройденных бинарным деревом, чтобы достичь любого листа дерева. Кроме того, узел называется листом, если у него нет дочерних узлов.
Пример:
Input: root = [1,3,2], k = 1
Output: 2
import java.util.*;
public class Solution {
public int findClosestLeaf(TreeNode root, int k) {
List<TreeNode> path = new ArrayList<>();
Map<TreeNode, Integer> leaves = new HashMap<>();
findPath(root, k, path);
findLeaves(root, leaves);
Queue<Pair<TreeNode, Integer>> queue = new LinkedList<>();
queue.add(new Pair<>(path.get(path.size() - 1), 0));
Set<TreeNode> visited = new HashSet<>();
while (!queue.isEmpty()) {
Pair<TreeNode, Integer> pair = queue.poll();
TreeNode node = pair.getKey();
int dist = pair.getValue();
if (leaves.containsKey(node)) return node.val;
visited.add(node);
if (node.left != null && !visited.contains(node.left)) queue.add(new Pair<>(node.left, dist + 1));
if (node.right != null && !visited.contains(node.right)) queue.add(new Pair<>(node.right, dist + 1));
if (path.size() > 1) queue.add(new Pair<>(path.remove(path.size() - 1), dist + 1));
}
return -1;
}
private boolean findPath(TreeNode node, int k, List<TreeNode> path) {
if (node == null) return false;
path.add(node);
if (node.val == k) return true;
if (findPath(node.left, k, path) || findPath(node.right, k, path)) return true;
path.remove(path.size() - 1);
return false;
}
private void findLeaves(TreeNode node, Map<TreeNode, Integer> leaves) {
if (node == null) return;
if (node.left == null && node.right == null) leaves.put(node, 0);
findLeaves(node.left, leaves);
findLeaves(node.right, leaves);
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 743. Network Delay Time
Дана сеть из узлов, помеченных от 1 до n. Также дано times - список времен прохождения сигнала в виде направленных ребер times[i] = (ui, vi, wi), где ui - исходный узел, vi - целевой узел, а wi - время прохождения сигнала от источника до цели. Мы пошлем сигнал из заданного узла k. Верните минимальное время, которое потребуется всем узлам, чтобы получить сигнал. Если все узлы не могут получить сигнал, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Представьте граф в виде списка смежности.
2⃣ Используйте алгоритм Дейкстры для нахождения кратчайших путей от узла k до всех других узлов.
3⃣ Найдите максимальное значение среди кратчайших путей к узлам. Если какой-либо узел недостижим, верните -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 743. Network Delay Time
Дана сеть из узлов, помеченных от 1 до n. Также дано times - список времен прохождения сигнала в виде направленных ребер times[i] = (ui, vi, wi), где ui - исходный узел, vi - целевой узел, а wi - время прохождения сигнала от источника до цели. Мы пошлем сигнал из заданного узла k. Верните минимальное время, которое потребуется всем узлам, чтобы получить сигнал. Если все узлы не могут получить сигнал, верните -1.
Пример:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2
import java.util.*;
public class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
Map<Integer, List<int[]>> graph = new HashMap<>();
for (int i = 1; i <= n; i++) {
graph.put(i, new ArrayList<>());
}
for (int[] time : times) {
graph.get(time[0]).add(new int[]{time[1], time[2]});
}
PriorityQueue<int[]> minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
minHeap.add(new int[]{0, k});
Map<Integer, Integer> minTime = new HashMap<>();
for (int i = 1; i <= n; i++) {
minTime.put(i, Integer.MAX_VALUE);
}
minTime.put(k, 0);
while (!minHeap.isEmpty()) {
int[] top = minHeap.poll();
int time = top[0];
int node = top[1];
for (int[] neighbor : graph.get(node)) {
int newTime = time + neighbor[1];
if (newTime < minTime.get(neighbor[0])) {
minTime.put(neighbor[0], newTime);
minHeap.add(new int[]{newTime, neighbor[0]});
}
}
}
int maxTime = Collections.max(minTime.values());
return maxTime == Integer.MAX_VALUE ? -1 : maxTime;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#easy
Задача: 744. Find Smallest Letter Greater Than Target
Нам дан массив символов letters, отсортированный в неубывающем порядке, и символ target. В массиве letters есть как минимум два разных символа. Возвращается наименьший символ в letters, который лексикографически больше target. Если такого символа не существует, возвращается первый символ в буквах.
Пример:
👨💻 Алгоритм:
1⃣ Использовать бинарный поиск для нахождения позиции первого символа в letters, который лексикографически больше target.
2⃣ Если найденный символ существует, вернуть его.
3⃣ Если такого символа не существует, вернуть первый символ в letters.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 744. Find Smallest Letter Greater Than Target
Нам дан массив символов letters, отсортированный в неубывающем порядке, и символ target. В массиве letters есть как минимум два разных символа. Возвращается наименьший символ в letters, который лексикографически больше target. Если такого символа не существует, возвращается первый символ в буквах.
Пример:
Input: letters = ["c","f","j"], target = "a"
Output: "c"
public class Solution {
public char nextGreatestLetter(char[] letters, char target) {
int left = 0, right = letters.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (letters[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return letters[left % letters.length];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM