#hard
Задача: 630. Course Schedule III
Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.
Пример:
👨💻 Алгоритм:
1⃣ Сортировка курсов
Отсортируйте курсы по их конечным датам (lastDay). Это позволяет проходить курсы как можно ближе к их крайним срокам.
2⃣ Проход по курсам
Используйте приоритетную очередь (max-heap) для отслеживания продолжительности пройденных курсов.
3⃣ Добавление и удаление курсов
Для каждого курса: Добавьте его продолжительность в приоритетную очередь и обновите общее время прохождения курсов. Если общее время превышает крайний срок текущего курса, удалите самый длительный курс из очереди и скорректируйте общее время.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 630. Course Schedule III
Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.
Пример:
Input: courses = [[100,200],[200,1300],[1000,1250],[2000,3200]]
Output: 3
Отсортируйте курсы по их конечным датам (lastDay). Это позволяет проходить курсы как можно ближе к их крайним срокам.
Используйте приоритетную очередь (max-heap) для отслеживания продолжительности пройденных курсов.
Для каждого курса: Добавьте его продолжительность в приоритетную очередь и обновите общее время прохождения курсов. Если общее время превышает крайний срок текущего курса, удалите самый длительный курс из очереди и скорректируйте общее время.
import heapq
def scheduleCourse(courses):
courses.sort(key=lambda x: x[1])
total_time = 0
max_heap = []
for duration, last_day in courses:
heapq.heappush(max_heap, -duration)
total_time += duration
if total_time > last_day:
total_time += heapq.heappop(max_heap)
return len(max_heap)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#easy
Задача: 434. Number of Segments in a String
Дана строка s, верните количество сегментов в строке.
Сегмент определяется как непрерывная последовательность символов, отличных от пробелов.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте счетчик сегментов segment_count равным 0.
2⃣ Итеративно пройдитесь по строке s. Для каждого индекса i проверьте, начинается ли на этом индексе сегмент: Если символ s[i] не является пробелом, и (либо это первый символ строки, либо предыдущий символ s[i-1] является пробелом), увеличьте segment_count.
3⃣ Верните segment_count.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 434. Number of Segments in a String
Дана строка s, верните количество сегментов в строке.
Сегмент определяется как непрерывная последовательность символов, отличных от пробелов.
Пример:
Input: s = "Hello, my name is John"
Output: 5
Explanation: The five segments are ["Hello,", "my", "name", "is", "John"]
class Solution:
def countSegments(self, s: str) -> int:
segment_count = 0
for i in range(len(s)):
if (i == 0 or s[i-1] == ' ') and s[i] != ' ':
segment_count += 1
return segment_count
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
#hard
Задача: 354. Russian Doll Envelopes
Вам дан двумерный массив целых чисел envelopes, где envelopes[i] = [wi, hi] представляет ширину и высоту конверта.
Один конверт может поместиться в другой, если и только если ширина и высота одного конверта больше ширины и высоты другого конверта.
Верните максимальное количество конвертов, которые вы можете вложить друг в друга (т.е. поместить один в другой).
Примечание: Вы не можете поворачивать конверт.
Пример:
👨💻 Алгоритм:
1⃣ Отсортируйте массив конвертов по возрастанию по первой размерности (ширине) и по убыванию по второй размерности (высоте).
2⃣ Извлеките вторую размерность (высоты) отсортированного массива.
3⃣ Найдите длину наибольшей возрастающей подпоследовательности в массиве высот.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 354. Russian Doll Envelopes
Вам дан двумерный массив целых чисел envelopes, где envelopes[i] = [wi, hi] представляет ширину и высоту конверта.
Один конверт может поместиться в другой, если и только если ширина и высота одного конверта больше ширины и высоты другого конверта.
Верните максимальное количество конвертов, которые вы можете вложить друг в друга (т.е. поместить один в другой).
Примечание: Вы не можете поворачивать конверт.
Пример:
Input: envelopes = [[5,4],[6,4],[6,7],[2,3]]
Output: 3
Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
dp = []
for num in nums:
i = bisect_left(dp, num)
if i < len(dp):
dp[i] = num
else:
dp.append(num)
return len(dp)
def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
envelopes.sort(key=lambda x: (x[0], -x[1]))
second_dim = [e[1] for e in envelopes]
return self.lengthOfLIS(second_dim)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
#hard
Задача: 631. Design Excel Sum Formula
Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Создайте класс Excel, который будет инициализировать матрицу нужного размера и хранить текущие значения ячеек. Реализуйте методы для установки значений, получения значений и вычисления суммы.
2⃣ Метод установки значений
Реализуйте метод set, который будет изменять значение ячейки в матрице.
3⃣ Метод вычисления суммы
Реализуйте метод sum, который будет вычислять сумму значений ячеек, указанных в списке numbers. Метод должен поддерживать как одиночные ячейки, так и диапазоны ячеек.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 631. Design Excel Sum Formula
Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.
Пример:
Input
["Excel", "set", "sum", "set", "get"]
[[3, "C"], [1, "A", 2], [3, "C", ["A1", "A1:B2"]], [2, "B", 2], [3, "C"]]
Output
[null, null, 4, null, 6]
Создайте класс Excel, который будет инициализировать матрицу нужного размера и хранить текущие значения ячеек. Реализуйте методы для установки значений, получения значений и вычисления суммы.
Реализуйте метод set, который будет изменять значение ячейки в матрице.
Реализуйте метод sum, который будет вычислять сумму значений ячеек, указанных в списке numbers. Метод должен поддерживать как одиночные ячейки, так и диапазоны ячеек.
class Excel:
def __init__(self, height: int, width: str):
self.mat = [[0] * (ord(width) - ord('A') + 1) for _ in range(height)]
self.formulas = {}
def set(self, row: int, column: str, val: int) -> None:
self.mat[row - 1][ord(column) - ord('A')] = val
self.formulas.pop((row, column), None)
def get(self, row: int, column: str) -> int:
if (row, column) in self.formulas:
return self._evaluate_formula(row, column)
return self.mat[row - 1][ord(column) - ord('A')]
def sum(self, row: int, column: str, numbers: List[str]) -> int:
self.formulas[(row, column)] = numbers
return self._evaluate_formula(row, column)
def _evaluate_formula(self, row: int, column: str) -> int:
total = 0
for number in self.formulas[(row, column)]:
if ':' in number:
start, end = number.split(':')
start_row, start_col = int(start[1:]), start[0]
end_row, end_col = int(end[1:]), end[0]
for r in range(start_row, end_row + 1):
for c in range(ord(start_col), ord(end_col) + 1):
total += self.get(r, chr(c))
else:
r, c = int(number[1:]), number[0]
total += self.get(r, c)
return total
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
#medium
Задача: 435. Non-overlapping Intervals
Дан массив интервалов intervals, где intervals[i] = [starti, endi]. Верните минимальное количество интервалов, которые нужно удалить, чтобы остальные интервалы не пересекались.
Пример:
👨💻 Алгоритм:
1⃣ Отсортируйте интервалы по времени окончания.
2⃣ Инициализируйте переменную ответа ans = 0 и целое число k для представления самого последнего времени окончания. k следует инициализировать небольшим значением, например, INT_MIN.
3⃣ Итеративно пройдитесь по интервалам. Для каждого интервала: Если время начала больше или равно k, обновите k до времени окончания текущего интервала. В противном случае увеличьте ans. Верните ans.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 435. Non-overlapping Intervals
Дан массив интервалов intervals, где intervals[i] = [starti, endi]. Верните минимальное количество интервалов, которые нужно удалить, чтобы остальные интервалы не пересекались.
Пример:
Input: intervals = [[1,2],[2,3],[3,4],[1,3]]
Output: 1
Explanation: [1,3] can be removed and the rest of the intervals are non-overlapping.
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
ans = 0
k = float('-inf')
for x, y in intervals:
if x >= k:
k = y
else:
ans += 1
return ans
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
ans = 0
k = float('-inf')
for x, y in intervals:
if x >= k:
k = y
else:
ans += 1
return ans
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#hard
Задача: 358. Rearrange String k Distance Apart
Дана строка s и целое число k, переставьте символы в s так, чтобы одинаковые символы находились на расстоянии не менее k друг от друга. Если невозможно переставить строку, верните пустую строку "".
Пример:
👨💻 Алгоритм:
1⃣ Создайте словарь частот для символов строки и определите максимальную частоту.
2⃣ Разделите символы на группы по частоте и создайте сегменты для размещения символов.
3⃣ Распределите оставшиеся символы по сегментам, проверяя условия, и объедините сегменты в итоговую строку.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 358. Rearrange String k Distance Apart
Дана строка s и целое число k, переставьте символы в s так, чтобы одинаковые символы находились на расстоянии не менее k друг от друга. Если невозможно переставить строку, верните пустую строку "".
Пример:
Input: s = "aabbcc", k = 3
Output: "abcabc"
Explanation: The same letters are at least a distance of 3 from each other.
from collections import defaultdict
class Solution:
def rearrangeString(self, s: str, k: int) -> str:
freqs = defaultdict(int)
max_freq = 0
for char in s:
freqs[char] += 1
max_freq = max(max_freq, freqs[char])
most_chars = {char for char, freq in freqs.items() if freq == max_freq}
second_chars = {char for char, freq in freqs.items() if freq == max_freq - 1}
segments = [list() for _ in range(max_freq)]
for i in range(max_freq):
for char in most_chars:
segments[i].append(char)
if i < max_freq - 1:
for char in second_chars:
segments[i].append(char)
segment_id = 0
for char, freq in freqs.items():
if char in most_chars or char in second_chars:
continue
for _ in range(freq):
segments[segment_id].append(char)
segment_id = (segment_id + 1) % (max_freq - 1)
for i in range(max_freq - 1):
if len(segments[i]) < k:
return ""
return "".join("".join(segment) for segment in segments)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
#hard
Задача: 632. Smallest Range Covering Elements from K Lists
У вас есть k списков отсортированных целых чисел в неубывающем порядке. Найдите наименьший диапазон, в который входит хотя бы одно число из каждого из k списков. Мы определяем, что диапазон [a, b] меньше диапазона [c, d], если b - a < d - c или a < c, если b - a == d - c.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и сбор всех начальных элементов
Создайте массив для хранения текущих индексов каждого списка и используйте минимальную кучу для отслеживания текущих минимальных элементов из каждого списка.
2⃣ Нахождение минимального диапазона
Используйте кучу для извлечения минимального элемента и обновления текущего диапазона. Обновляйте максимальный элемент в текущем диапазоне при добавлении новых элементов.
3⃣ Проверка и обновление диапазона
Продолжайте обновлять кучу и диапазон, пока возможно. Завершите, когда один из списков исчерпан.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 632. Smallest Range Covering Elements from K Lists
У вас есть k списков отсортированных целых чисел в неубывающем порядке. Найдите наименьший диапазон, в который входит хотя бы одно число из каждого из k списков. Мы определяем, что диапазон [a, b] меньше диапазона [c, d], если b - a < d - c или a < c, если b - a == d - c.
Пример:
Input: nums = [[4,10,15,24,26],[0,9,12,20],[5,18,22,30]]
Output: [20,24]
Создайте массив для хранения текущих индексов каждого списка и используйте минимальную кучу для отслеживания текущих минимальных элементов из каждого списка.
Используйте кучу для извлечения минимального элемента и обновления текущего диапазона. Обновляйте максимальный элемент в текущем диапазоне при добавлении новых элементов.
Продолжайте обновлять кучу и диапазон, пока возможно. Завершите, когда один из списков исчерпан.
from heapq import heappop, heappush
def smallestRange(nums):
min_heap = []
max_value = float('-inf')
for i in range(len(nums)):
heappush(min_heap, (nums[i][0], i, 0))
max_value = max(max_value, nums[i][0])
range_start, range_end = float('-inf'), float('inf')
while len(min_heap) == len(nums):
min_value, row, col = heappop(min_heap)
if max_value - min_value < range_end - range_start:
range_start, range_end = min_value, max_value
if col + 1 < len(nums[row]):
heappush(min_heap, (nums[row][col + 1], row, col + 1))
max_value = max(max_value, nums[row][col + 1])
return [range_start, range_end]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
#easy
Задача: 559. Maximum Depth of N-ary Tree
Дано n-арное дерево, найдите его максимальную глубину.
Максимальная глубина - это количество узлов вдоль самого длинного пути от корневого узла до самого дальнего листового узла.
Сериализация ввода n-арного дерева представлена в порядке уровня, каждая группа дочерних узлов разделена значением null (см. примеры).
Пример:
👨💻 Алгоритм:
1⃣ Интуитивный подход заключается в решении задачи с помощью рекурсии.
2⃣ Здесь мы демонстрируем пример с использованием стратегии поиска в глубину (DFS - Depth First Search).
3⃣ Применяя DFS, проходим через все узлы дерева, вычисляя максимальную глубину.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 559. Maximum Depth of N-ary Tree
Дано n-арное дерево, найдите его максимальную глубину.
Максимальная глубина - это количество узлов вдоль самого длинного пути от корневого узла до самого дальнего листового узла.
Сериализация ввода n-арного дерева представлена в порядке уровня, каждая группа дочерних узлов разделена значением null (см. примеры).
Пример:
Input: root = [1,null,3,2,4,null,5,6]
Output: 3
class Solution:
def maxDepth(self, root: 'Node') -> int:
if root is None:
return 0
elif not root.children:
return 1
else:
heights = [self.maxDepth(child) for child in root.children]
return max(heights) + 1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🤯1
#medium
Задача: 560. Subarray Sum Equals K
Дан массив целых чисел nums и целое число k, вернуть общее количество подмассивов, сумма которых равна k.
Подмассив - это непрерывная непустая последовательность элементов внутри массива.
Пример:
👨💻 Алгоритм:
1⃣ Самый простой метод - рассмотреть каждый возможный подмассив данного массива nums.
2⃣ Найти сумму элементов каждого из этих подмассивов и проверить равенство полученной суммы с заданным k.
3⃣ Всякий раз, когда сумма равна k, увеличить счетчик, используемый для хранения необходимого результата.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 560. Subarray Sum Equals K
Дан массив целых чисел nums и целое число k, вернуть общее количество подмассивов, сумма которых равна k.
Подмассив - это непрерывная непустая последовательность элементов внутри массива.
Пример:
Input: nums = [1,1,1], k = 2
Output: 2
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
count = 0
for start in range(len(nums)):
for end in range(start + 1, len(nums) + 1):
sum_ = sum(nums[start:end])
if sum_ == k:
count += 1
return count
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
#easy
Задача: 561. Array Partition
Дан массив целых чисел nums из 2n элементов. Разделите эти числа на n пар (a1, b1), (a2, b2), ..., (an, bn) так, чтобы сумма min(ai, bi) для всех i была максимальной. Верните максимальную сумму.
Пример:
👨💻 Алгоритм:
1⃣ Отсортируйте массив nums в неубывающем порядке.
2⃣ Итерируйте через массив, выбирая каждый второй элемент (начиная с первого).
3⃣ Суммируйте выбранные элементы и верните эту сумму.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 561. Array Partition
Дан массив целых чисел nums из 2n элементов. Разделите эти числа на n пар (a1, b1), (a2, b2), ..., (an, bn) так, чтобы сумма min(ai, bi) для всех i была максимальной. Верните максимальную сумму.
Пример:
Input: nums = [1,4,3,2]
Output: 4
Explanation: All possible pairings (ignoring the ordering of elements) are:
1. (1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3
2. (1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3
3. (1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4
So the maximum possible sum is 4.
class Solution:
def arrayPairSum(self, nums: List[int]) -> int:
nums.sort()
return sum(nums[i] for i in range(0, len(nums), 2))
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2
#medium
Задача: 562. Longest Line of Consecutive One in Matrix
Дана бинарная матрица размера m x n. Вернуть длину самой длинной последовательной линии из единиц в матрице.
Линия может быть горизонтальной, вертикальной, диагональной или анти-диагональной.
Пример:
👨💻 Алгоритм:
1⃣ Создайте 3 матрицы для хранения текущей длины последовательных единиц: horizontal, vertical, diagonal и anti_diagonal.
2⃣ Итерируйте через каждый элемент матрицы: Если элемент равен 1, обновите соответствующие значения в матрицах horizontal, vertical, diagonal и anti_diagonal. Обновите максимальную длину последовательной линии.
3⃣ Верните максимальную длину.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 562. Longest Line of Consecutive One in Matrix
Дана бинарная матрица размера m x n. Вернуть длину самой длинной последовательной линии из единиц в матрице.
Линия может быть горизонтальной, вертикальной, диагональной или анти-диагональной.
Пример:
Input: mat = [[0,1,1,0],[0,1,1,0],[0,0,0,1]]
Output: 3
class Solution:
def longestLine(self, mat: List[List[int]]) -> int:
if not mat or not mat[0]:
return 0
m, n = len(mat), len(mat[0])
max_length = 0
horizontal = [[0] * n for _ in range(m)]
vertical = [[0] * n for _ in range(m)]
diagonal = [[0] * n for _ in range(m)]
anti_diagonal = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
if mat[i][j] == 1:
horizontal[i][j] = (horizontal[i][j-1] if j > 0 else 0) + 1
vertical[i][j] = (vertical[i-1][j] if i > 0 else 0) + 1
diagonal[i][j] = (diagonal[i-1][j-1] if i > 0 and j > 0 else 0) + 1
anti_diagonal[i][j] = (anti_diagonal[i-1][j+1] if i > 0 and j < n-1 else 0) + 1
max_length = max(max_length, horizontal[i][j], vertical[i][j], diagonal[i][j], anti_diagonal[i][j])
return max_length
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Forwarded from easyoffer
easyoffer
Backend
Python | Вопросы
Python | Удалёнка
Python | LeetCode
Python | Тесты
Frontend | Вопросы
Frontend | Удалёнка
JavaScript | LeetCode
Frontend | Тесты
Java | Вопросы
Java | Удалёнка
Java | LeetCode
Java | Тесты
Тестировщик | Вопросы
Тестировщик | Удалёнка
Тестировщик | Тесты
Data Science | Вопросы
Data Science | Удалёнка
Data Science | Тесты
C# | Вопросы
C# | Удалёнка
C# | LeetCode
C# | Тесты
C/C++ | Вопросы
C/C++ | Удалёнка
C/C++ | LeetCode
C/C++ | Тесты
Golang | Вопросы
Golang | Удалёнка
Golang | LeetCode
Golang | Тесты
DevOps | Вопросы
DevOps | Удалёнка
DevOps | Тесты
PHP | Вопросы
PHP | Удалёнка
PHP | LeetCode
PHP | Тесты
Kotlin | Вопросы
Kotlin | Удалёнка
Kotlin | LeetCode
Kotlin | Тесты
Swift | Вопросы
Swift | Удалёнка
Swift | LeetCode
Swift | Тесты
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#easy
Задача: 563. Binary Tree Tilt
Дано корневое значение бинарного дерева. Вернуть сумму значений наклонов всех узлов дерева.
Наклон узла дерева - это абсолютная разница между суммой всех значений узлов левого поддерева и всех значений узлов правого поддерева. Если у узла нет левого потомка, то сумма значений узлов левого поддерева считается равной 0. То же правило применяется, если у узла нет правого потомка.
Пример:
👨💻 Алгоритм:
1⃣ Определите рекурсивную функцию, которая вычисляет сумму значений узлов поддерева и наклон текущего узла.
2⃣ Для каждого узла вычислите сумму значений левого и правого поддерева, а также их наклон, добавляя наклон к общей сумме.
3⃣ Верните общую сумму наклонов всех узлов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 563. Binary Tree Tilt
Дано корневое значение бинарного дерева. Вернуть сумму значений наклонов всех узлов дерева.
Наклон узла дерева - это абсолютная разница между суммой всех значений узлов левого поддерева и всех значений узлов правого поддерева. Если у узла нет левого потомка, то сумма значений узлов левого поддерева считается равной 0. То же правило применяется, если у узла нет правого потомка.
Пример:
Input: root = [1,2,3]
Output: 1
Explanation:
Tilt of node 2 : |0-0| = 0 (no children)
Tilt of node 3 : |0-0| = 0 (no children)
Tilt of node 1 : |2-3| = 1 (left subtree is just left child, so sum is 2; right subtree is just right child, so sum is 3)
Sum of every tilt : 0 + 0 + 1 = 1
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def findTilt(self, root: TreeNode) -> int:
self.total_tilt = 0
def sum_and_tilt(node):
if not node:
return 0
left_sum = sum_and_tilt(node.left)
right_sum = sum_and_tilt(node.right)
node_tilt = abs(left_sum - right_sum)
self.total_tilt += node_tilt
return node.val + left_sum + right_sum
sum_and_tilt(root)
return self.total_tilt
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🔥1
#medium
Задача: 565. Array Nesting
Дан массив целых чисел nums длиной n, где nums является перестановкой чисел в диапазоне [0, n - 1].
Вы должны построить множество s[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ...} при соблюдении следующего правила:
Первый элемент в s[k] начинается с выбора элемента nums[k] с индексом k.
Следующий элемент в s[k] должен быть nums[nums[k]], затем nums[nums[nums[k]]], и так далее.
Мы прекращаем добавлять элементы непосредственно перед тем, как в s[k] появится дубликат.
Верните длину самого длинного множества s[k].
Пример:
👨💻 Алгоритм:
1⃣ Создайте массив для отслеживания посещенных элементов.
2⃣ Для каждого элемента в nums, если он не посещен, начните формирование множества s[k], последовательно переходя по элементам, пока не встретится уже посещенный элемент.
3⃣ Обновите максимальную длину найденного множества.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 565. Array Nesting
Дан массив целых чисел nums длиной n, где nums является перестановкой чисел в диапазоне [0, n - 1].
Вы должны построить множество s[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ...} при соблюдении следующего правила:
Первый элемент в s[k] начинается с выбора элемента nums[k] с индексом k.
Следующий элемент в s[k] должен быть nums[nums[k]], затем nums[nums[nums[k]]], и так далее.
Мы прекращаем добавлять элементы непосредственно перед тем, как в s[k] появится дубликат.
Верните длину самого длинного множества s[k].
Пример:
Input: nums = [5,4,0,3,1,6,2]
Output: 4
Explanation:
nums[0] = 5, nums[1] = 4, nums[2] = 0, nums[3] = 3, nums[4] = 1, nums[5] = 6, nums[6] = 2.
One of the longest sets s[k]:
s[0] = {nums[0], nums[5], nums[6], nums[2]} = {5, 6, 2, 0}
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
visited = [False] * len(nums)
max_length = 0
for i in range(len(nums)):
if not visited[i]:
start = i
count = 0
while not visited[start]:
visited[start] = True
start = nums[start]
count += 1
max_length = max(max_length, count)
return max_length
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
#medium
Задача: 1530. Number of Good Leaf Nodes Pairs
Вам дан корень бинарного дерева и целое число distance. Пара двух различных листовых узлов бинарного дерева называется хорошей, если длина кратчайшего пути между ними меньше или равна distance.
Верните количество хороших пар листовых узлов в дереве.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте список смежности для преобразования дерева в граф и множество для хранения листовых узлов. Используйте вспомогательный метод traverseTree для обхода дерева, чтобы построить граф и найти листовые узлы. В параметрах поддерживайте текущий узел, а также родительский узел. Если текущий узел является листом, добавьте его в множество. В списке смежности добавьте текущий узел в список соседей родительского узла и наоборот. Рекурсивно вызовите traverseTree для левого и правого дочернего узла текущего узла.
2⃣ Инициализируйте переменную ans для подсчета количества хороших пар листовых узлов. Итеративно переберите каждый листовой узел в множестве. Запустите BFS для текущего листового узла. BFS можно прервать досрочно, как только будут обнаружены все узлы, находящиеся на расстоянии от текущего листового узла. Увеличьте ans для каждого листового узла, найденного в каждом запуске BFS.
3⃣ Верните ans / 2. Мы считаем каждую пару дважды, поэтому нужно разделить на 2, чтобы получить фактическое количество.
😎 Решение🐍
Ставь 👍 и забирай 📚 Базу знаний
Задача: 1530. Number of Good Leaf Nodes Pairs
Вам дан корень бинарного дерева и целое число distance. Пара двух различных листовых узлов бинарного дерева называется хорошей, если длина кратчайшего пути между ними меньше или равна distance.
Верните количество хороших пар листовых узлов в дереве.
Пример:
Input: root = [1,2,3,null,4], distance = 3
Output: 1
Explanation: The leaf nodes of the tree are 3 and 4 and the length of the shortest path between them is 3. This is the only good pair.
class Solution:
def countPairs(self, root: TreeNode, distance: int) -> int:
graph = defaultdict(list)
leafNodes = set()
self.traverseTree(root, None, graph, leafNodes)
ans = 0
for leaf in leafNodes:
bfsQueue = deque([leaf])
seen = set([leaf])
for i in range(distance + 1):
size = len(bfsQueue)
for _ in range(size):
currNode = bfsQueue.popleft()
if currNode in leafNodes and currNode != leaf:
ans += 1
for neighbor in graph[currNode]:
if neighbor not in seen:
bfsQueue.append(neighbor)
seen.add(neighbor)
return ans // 2
def traverseTree(self, currNode, prevNode, graph, leafNodes):
if not currNode:
return
if not currNode.left and not currNode.right:
leafNodes.add(currNode)
if prevNode:
graph[prevNode].append(currNode)
graph[currNode].append(prevNode)
self.traverseTree(currNode.left, currNode, graph, leafNodes)
self.traverseTree(currNode.right, currNode, graph, leafNodes)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1🔥1
#medium
Задача: 669. Trim a Binary Search Tree
Дано корневое дерево двоичного поиска и нижняя и верхняя границы как low и high. Обрежьте дерево так, чтобы все его элементы лежали в диапазоне [low, high]. Обрезка дерева не должна изменять относительную структуру элементов, которые останутся в дереве (то есть любой потомок узла должен оставаться потомком). Можно доказать, что существует единственный ответ.
Верните корень обрезанного дерева двоичного поиска. Обратите внимание, что корень может измениться в зависимости от заданных границ.
Пример:
👨💻 Алгоритм:
1⃣ Если node.val > high, то обрезанное двоичное дерево должно находиться слева от узла.
2⃣ Если node.val < low, то обрезанное двоичное дерево должно находиться справа от узла.
3⃣ В противном случае обрезаем обе стороны дерева.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 669. Trim a Binary Search Tree
Дано корневое дерево двоичного поиска и нижняя и верхняя границы как low и high. Обрежьте дерево так, чтобы все его элементы лежали в диапазоне [low, high]. Обрезка дерева не должна изменять относительную структуру элементов, которые останутся в дереве (то есть любой потомок узла должен оставаться потомком). Можно доказать, что существует единственный ответ.
Верните корень обрезанного дерева двоичного поиска. Обратите внимание, что корень может измениться в зависимости от заданных границ.
Пример:
Input: root = [1,0,2], low = 1, high = 2
Output: [1,null,2]
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
if not root:
return None
if root.val > high:
return self.trimBST(root.left, low, high)
if root.val < low:
return self.trimBST(root.right, low, high)
root.left = self.trimBST(root.left, low, high)
root.right = self.trimBST(root.right, low, high)
return root
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
#medium
Задача: 309. Best Time to Buy and Sell Stock with Cooldown
Дан массив prices, где prices[i] — цена данной акции в i-й день.
Найдите максимальную прибыль, которую можно получить. Вы можете совершить любое количество транзакций (т. е. купить и продать одну акцию несколько раз) с следующими ограничениями:
После продажи акции вы не можете покупать акции на следующий день (т. е. необходимо один день подождать).
Пример:
👨💻 Алгоритм:
1⃣ Инициализация состояний
Используйте три состояния для отслеживания максимальной прибыли: hold: максимальная прибыль на данный день, если у вас есть акция. sold: максимальная прибыль на данный день, если вы продали акцию. cooldown: максимальная прибыль на данный день, если вы находитесь в периоде ожидания после продажи.
2⃣ Обновление состояний
Итерируйте по каждому дню, обновляя состояния: hold: максимальная прибыль, если у вас есть акция на текущий день. sold: максимальная прибыль, если вы продаете акцию на текущий день. cooldown: максимальная прибыль, если вы находитесь в периоде ожидания на текущий день.
3⃣ Определение максимальной прибыли
В конце итерации максимальная прибыль будет максимальным значением между состояниями sold и cooldown, так как hold состояние не может быть конечным состоянием для получения максимальной прибыли.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 309. Best Time to Buy and Sell Stock with Cooldown
Дан массив prices, где prices[i] — цена данной акции в i-й день.
Найдите максимальную прибыль, которую можно получить. Вы можете совершить любое количество транзакций (т. е. купить и продать одну акцию несколько раз) с следующими ограничениями:
После продажи акции вы не можете покупать акции на следующий день (т. е. необходимо один день подождать).
Пример:
Input: prices = [1]
Output: 0
Используйте три состояния для отслеживания максимальной прибыли: hold: максимальная прибыль на данный день, если у вас есть акция. sold: максимальная прибыль на данный день, если вы продали акцию. cooldown: максимальная прибыль на данный день, если вы находитесь в периоде ожидания после продажи.
Итерируйте по каждому дню, обновляя состояния: hold: максимальная прибыль, если у вас есть акция на текущий день. sold: максимальная прибыль, если вы продаете акцию на текущий день. cooldown: максимальная прибыль, если вы находитесь в периоде ожидания на текущий день.
В конце итерации максимальная прибыль будет максимальным значением между состояниями sold и cooldown, так как hold состояние не может быть конечным состоянием для получения максимальной прибыли.
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
n = len(prices)
hold = -prices[0]
sold = 0
cooldown = 0
for i in range(1, n):
new_hold = max(hold, cooldown - prices[i])
new_sold = hold + prices[i]
new_cooldown = max(cooldown, sold)
hold = new_hold
sold = new_sold
cooldown = new_cooldown
return max(sold, cooldown)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1🔥1
#medium
Задача: 670. Maximum Swap
Дано целое число num. Вы можете поменять местами две цифры не более одного раза, чтобы получить число с наибольшим значением.
Верните число с наибольшим значением, которое можно получить.
Пример:
👨💻 Алгоритм:
1⃣ Сохраняем кандидатов как списки длины len(num). Для каждой пары позиций (i, j) выполняем обмен цифр, записываем кандидата, если он больше текущего ответа, затем возвращаем цифры обратно.
2⃣ Проверяем, что не добавили ведущий ноль. Фактически, проверять это не нужно, так как изначальное число его не содержит.
3⃣ Возвращаем максимальное значение из всех кандидатов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 670. Maximum Swap
Дано целое число num. Вы можете поменять местами две цифры не более одного раза, чтобы получить число с наибольшим значением.
Верните число с наибольшим значением, которое можно получить.
Пример:
Input: num = 2736
Output: 7236
Explanation: Swap the number 2 and the number 7.
class Solution:
def maximumSwap(self, num: int) -> int:
A = list(str(num))
ans = A[:]
for i in range(len(A)):
for j in range(i + 1, len(A)):
A[i], A[j] = A[j], A[i]
for k in range(len(A)):
if A[k] != ans[k]:
if A[k] > ans[k]:
ans = A[:]
break
A[i], A[j] = A[j], A[i]
return int(''.join(ans))
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
#medium
Задача: 310. Minimum Height Trees
Дерево — это неориентированный граф, в котором любые две вершины соединены ровно одним путем. Другими словами, любое связное граф без простых циклов является деревом.
Дано дерево из n узлов, помеченных от 0 до n - 1, и массив из n - 1 ребер, где edges[i] = [ai, bi] указывает на наличие неориентированного ребра между узлами ai и bi в дереве. Вы можете выбрать любой узел дерева в качестве корня. Когда вы выбираете узел x в качестве корня, дерево имеет высоту h. Среди всех возможных корневых деревьев те, которые имеют минимальную высоту (то есть min(h)), называются деревьями с минимальной высотой (MHT).
Верните список всех меток корней MHT. Вы можете вернуть ответ в любом порядке.
Высота корневого дерева — это количество ребер на самом длинном нисходящем пути между корнем и листом.
Пример:
👨💻 Алгоритм:
1⃣ Создание списка смежности
Создайте список смежности, представляющий граф.
2⃣ Удаление листьев
Начните с удаления всех листьев. Лист — это узел с одной гранью. В каждой итерации удаляйте текущие листья и обновляйте список смежности. Новые листья будут вершинами, которые стали листьями после удаления предыдущих листьев.
3⃣ Повторение процесса
Повторяйте процесс до тех пор, пока не останется два или менее узлов. Эти узлы будут корнями деревьев с минимальной высотой (MHT).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 310. Minimum Height Trees
Дерево — это неориентированный граф, в котором любые две вершины соединены ровно одним путем. Другими словами, любое связное граф без простых циклов является деревом.
Дано дерево из n узлов, помеченных от 0 до n - 1, и массив из n - 1 ребер, где edges[i] = [ai, bi] указывает на наличие неориентированного ребра между узлами ai и bi в дереве. Вы можете выбрать любой узел дерева в качестве корня. Когда вы выбираете узел x в качестве корня, дерево имеет высоту h. Среди всех возможных корневых деревьев те, которые имеют минимальную высоту (то есть min(h)), называются деревьями с минимальной высотой (MHT).
Верните список всех меток корней MHT. Вы можете вернуть ответ в любом порядке.
Высота корневого дерева — это количество ребер на самом длинном нисходящем пути между корнем и листом.
Пример:
Input: n = 4, edges = [[1,0],[1,2],[1,3]]
Output: [1]
Explanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.
Создайте список смежности, представляющий граф.
Начните с удаления всех листьев. Лист — это узел с одной гранью. В каждой итерации удаляйте текущие листья и обновляйте список смежности. Новые листья будут вершинами, которые стали листьями после удаления предыдущих листьев.
Повторяйте процесс до тех пор, пока не останется два или менее узлов. Эти узлы будут корнями деревьев с минимальной высотой (MHT).
class Solution:
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
if n == 1:
return [0]
from collections import defaultdict, deque
adj = defaultdict(list)
for u, v in edges:
adj[u].append(v)
adj[v].append(u)
leaves = deque()
for i in range(n):
if len(adj[i]) == 1:
leaves.append(i)
remaining_nodes = n
while remaining_nodes > 2:
leaves_size = len(leaves)
remaining_nodes -= leaves_size
for _ in range(leaves_size):
leaf = leaves.popleft()
neighbor = adj[leaf].pop()
adj[neighbor].remove(leaf)
if len(adj[neighbor]) == 1:
leaves.append(neighbor)
return list(leaves)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1
#medium
Задача: 672. Bulb Switcher II
Есть комната с n лампочками, пронумерованными от 1 до n, которые изначально все включены, и четыре кнопки на стене. Каждая из четырех кнопок имеет разную функциональность:
Кнопка 1: Переключает состояние всех лампочек.
Кнопка 2: Переключает состояние всех лампочек с четными номерами (т.е. 2, 4, ...).
Кнопка 3: Переключает состояние всех лампочек с нечетными номерами (т.е. 1, 3, ...).
Кнопка 4: Переключает состояние всех лампочек с номером j = 3k + 1, где k = 0, 1, 2, ... (т.е. 1, 4, 7, 10, ...).
Необходимо сделать ровно presses нажатий кнопок. Для каждого нажатия можно выбрать любую из четырех кнопок для нажатия.
Даны два целых числа n и presses, вернуть количество различных возможных состояний после выполнения всех presses нажатий кнопок.
Пример:
👨💻 Алгоритм:
1⃣ Рассчитаем возможные множества остатков: то есть какие множества c_i = f_i (mod 2) возможны.
2⃣ Так как c_i ≡ f_i и c_i ≤ f_i, если ∑f_i ≠ ∑c_i, или если ∑f_i < ∑c_i, это невозможно. В противном случае это возможно простым построением: выполните операции, указанные c_i, затем выполните операцию номер 1 с четным числом оставшихся операций.
3⃣ Для каждого возможного множества остатков симулируем и запоминаем, как будут выглядеть первые 6 лампочек, сохраняя это в структуре Set. В конце возвращаем размер этого множества.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 672. Bulb Switcher II
Есть комната с n лампочками, пронумерованными от 1 до n, которые изначально все включены, и четыре кнопки на стене. Каждая из четырех кнопок имеет разную функциональность:
Кнопка 1: Переключает состояние всех лампочек.
Кнопка 2: Переключает состояние всех лампочек с четными номерами (т.е. 2, 4, ...).
Кнопка 3: Переключает состояние всех лампочек с нечетными номерами (т.е. 1, 3, ...).
Кнопка 4: Переключает состояние всех лампочек с номером j = 3k + 1, где k = 0, 1, 2, ... (т.е. 1, 4, 7, 10, ...).
Необходимо сделать ровно presses нажатий кнопок. Для каждого нажатия можно выбрать любую из четырех кнопок для нажатия.
Даны два целых числа n и presses, вернуть количество различных возможных состояний после выполнения всех presses нажатий кнопок.
Пример:
Input: n = 1, presses = 1
Output: 2
Explanation: Status can be:
- [off] by pressing button 1
- [on] by pressing button 2
class Solution:
def flipLights(self, n: int, m: int) -> int:
seen = set()
n = min(n, 6)
shift = max(0, 6 - n)
for cand in range(16):
bcount = bin(cand).count('1')
if bcount % 2 == m % 2 and bcount <= m:
lights = 0
if ((cand >> 0) & 1) > 0: lights ^= 0b111111 >> shift
if ((cand >> 1) & 1) > 0: lights ^= 0b010101 >> shift
if ((cand >> 2) & 1) > 0: lights ^= 0b101010 >> shift
if ((cand >> 3) & 1) > 0: lights ^= 0b100100 >> shift
seen.add(lights)
return len(seen)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1
#medium
Задача: 311. Sparse Matrix Multiplication
Даны две разреженные матрицы mat1 размером m x k и mat2 размером k x n. Верните результат перемножения матриц mat1 x mat2. Вы можете предположить, что умножение всегда возможно.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация результирующей матрицы
Создайте результирующую матрицу result размером m x n, заполненную нулями.
2⃣ Хранение ненулевых элементов
Пройдите по каждой строке матрицы mat1 и сохраните индексы и значения ненулевых элементов в хеш-карте mat1_map. Пройдите по каждой колонке матрицы mat2 и сохраните индексы и значения ненулевых элементов в хеш-карте mat2_map.
3⃣ Вычисление произведения
Для каждой строки i в mat1 и для каждой колонки j в mat2: Если в mat1_map есть ненулевой элемент в строке i и в mat2_map есть ненулевой элемент в колонке j с одинаковым индексом k, добавьте произведение этих элементов к result[i][j].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 311. Sparse Matrix Multiplication
Даны две разреженные матрицы mat1 размером m x k и mat2 размером k x n. Верните результат перемножения матриц mat1 x mat2. Вы можете предположить, что умножение всегда возможно.
Пример:
Input: mat1 = [[1,0,0],[-1,0,3]], mat2 = [[7,0,0],[0,0,0],[0,0,1]]
Output: [[7,0,0],[-7,0,3]]
Создайте результирующую матрицу result размером m x n, заполненную нулями.
Пройдите по каждой строке матрицы mat1 и сохраните индексы и значения ненулевых элементов в хеш-карте mat1_map. Пройдите по каждой колонке матрицы mat2 и сохраните индексы и значения ненулевых элементов в хеш-карте mat2_map.
Для каждой строки i в mat1 и для каждой колонки j в mat2: Если в mat1_map есть ненулевой элемент в строке i и в mat2_map есть ненулевой элемент в колонке j с одинаковым индексом k, добавьте произведение этих элементов к result[i][j].
class Solution:
def multiply(self, mat1: List[List[int]], mat2: List[List[int]]) -> List[List[int]]:
n = len(mat1)
k = len(mat1[0])
m = len(mat2[0])
ans = [[0] * m for _ in range(n)]
for rowIndex in range(n):
for elementIndex in range(k):
if mat1[rowIndex][elementIndex] != 0:
for colIndex in range(m):
ans[rowIndex][colIndex] += mat1[rowIndex][elementIndex] * mat2[elementIndex][colIndex]
return ans
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👀1