Задача: 904. Fruit Into Baskets
Сложность: medium
Вы посещаете ферму, где в один ряд слева направо расположены фруктовые деревья. Деревья представлены целочисленным массивом fruits, где fruits[i] - это тип фрукта, который производит i-е дерево. Вы хотите собрать как можно больше фруктов. Однако у владельца есть строгие правила, которым вы должны следовать: у вас есть только две корзины, и каждая корзина может содержать только один тип фруктов. Количество фруктов в каждой корзине не ограничено. Начиная с любого дерева по вашему выбору, вы должны собрать ровно один фрукт с каждого дерева (включая начальное), двигаясь при этом вправо. Собранные фрукты должны поместиться в одну из ваших корзин. Как только вы достигнете дерева с фруктами, которые не могут поместиться в ваши корзины, вы должны остановиться. Учитывая целочисленный массив fruits, верните максимальное количество фруктов, которое вы можете собрать.
Пример:
👨💻 Алгоритм:
1⃣ Использовать метод скользящего окна для поддержания текущего подмассива, содержащего не более двух типов фруктов.
2⃣ Перемещать правый указатель, расширяя окно, и обновлять количество каждого типа фрукта в окне.
Если количество типов фруктов в окне превышает два, перемещать левый указатель, уменьшая окно, пока в окне снова не будет не более двух типов фруктов.
3⃣ Подсчитывать максимальное количество фруктов, собранных на каждом шаге.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вы посещаете ферму, где в один ряд слева направо расположены фруктовые деревья. Деревья представлены целочисленным массивом fruits, где fruits[i] - это тип фрукта, который производит i-е дерево. Вы хотите собрать как можно больше фруктов. Однако у владельца есть строгие правила, которым вы должны следовать: у вас есть только две корзины, и каждая корзина может содержать только один тип фруктов. Количество фруктов в каждой корзине не ограничено. Начиная с любого дерева по вашему выбору, вы должны собрать ровно один фрукт с каждого дерева (включая начальное), двигаясь при этом вправо. Собранные фрукты должны поместиться в одну из ваших корзин. Как только вы достигнете дерева с фруктами, которые не могут поместиться в ваши корзины, вы должны остановиться. Учитывая целочисленный массив fruits, верните максимальное количество фруктов, которое вы можете собрать.
Пример:
Input: fruits = [1,2,1]
Output: 3
Если количество типов фруктов в окне превышает два, перемещать левый указатель, уменьшая окно, пока в окне снова не будет не более двух типов фруктов.
def totalFruit(fruits):
from collections import defaultdict
basket = defaultdict(int)
left = 0
max_fruits = 0
for right in range(len(fruits)):
basket[fruits[right]] += 1
while len(basket) > 2:
basket[fruits[left]] -= 1
if basket[fruits[left]] == 0:
del basket[fruits[left]]
left += 1
max_fruits = max(max_fruits, right - left + 1)
return max_fruits
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
Задача: 688. Knight Probability in Chessboard
Сложность: medium
На шахматной доске размером n x n конь начинает в клетке (row, column) и пытается сделать ровно k ходов. Строки и столбцы нумеруются с 0, так что верхняя левая клетка — это (0, 0), а нижняя правая — (n - 1, n - 1).
Шахматный конь имеет восемь возможных ходов, как показано ниже. Каждый ход — это два поля в кардинальном направлении, затем одно поле в ортогональном направлении.
Каждый раз, когда конь делает ход, он случайным образом выбирает один из восьми возможных ходов (даже если этот ход выведет его за пределы шахматной доски) и перемещается туда.
Конь продолжает двигаться, пока не сделает ровно k ходов или не выйдет за пределы доски.
Верните вероятность того, что конь останется на доске после того, как он завершит свои ходы.
Пример:
👨💻 Алгоритм:
1⃣ Определите возможные направления для ходов коня в directions. Инициализируйте таблицу динамического программирования dp нулями. Установите dp[0][row][column] равным 1, что представляет начальную позицию коня.
2⃣ Итерация по ходам от 1 до k. Итерация по строкам от 0 до n−1. Итерация по столбцам от 0 до n−1. Итерация по возможным направлениям: вычислите i' как i минус вертикальный компонент направления. Вычислите j' как j минус горизонтальный компонент направления. Проверьте, находятся ли i' и j' в диапазоне [0, n−1]. Если находятся, добавьте (1/8) * dp[moves−1][i'][j'] к dp[moves][i][j].
3⃣ Вычислите общую вероятность, суммируя все значения в dp[k]. Верните общую вероятность.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
На шахматной доске размером n x n конь начинает в клетке (row, column) и пытается сделать ровно k ходов. Строки и столбцы нумеруются с 0, так что верхняя левая клетка — это (0, 0), а нижняя правая — (n - 1, n - 1).
Шахматный конь имеет восемь возможных ходов, как показано ниже. Каждый ход — это два поля в кардинальном направлении, затем одно поле в ортогональном направлении.
Каждый раз, когда конь делает ход, он случайным образом выбирает один из восьми возможных ходов (даже если этот ход выведет его за пределы шахматной доски) и перемещается туда.
Конь продолжает двигаться, пока не сделает ровно k ходов или не выйдет за пределы доски.
Верните вероятность того, что конь останется на доске после того, как он завершит свои ходы.
Пример:
Input: n = 3, k = 2, row = 0, column = 0
Output: 0.06250
Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board.
From each of those positions, there are also two moves that will keep the knight on the board.
The total probability the knight stays on the board is 0.0625.
class Solution:
def knightProbability(self, n: int, k: int, row: int, column: int) -> float:
directions = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
dp = [[[0] * n for _ in range(n)] for _ in range(k + 1)]
dp[0][row][column] = 1
for moves in range(1, k + 1):
for i in range(n):
for j in range(n):
for direction in directions:
prevI, prevJ = i - direction[0], j - direction[1]
if 0 <= prevI < n and 0 <= prevJ < n:
dp[moves][i][j] += dp[moves - 1][prevI][prevJ] / 8
return sum(map(sum, dp[k]))
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Forwarded from easyoffer
Я боялся, что провалю собеседование. Так появился easyoffer
Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.
Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.
Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.
📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)
В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..
Тогда и пришла идея
А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.
Так родился easyoffer.
Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.
Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.
В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни
Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.
Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.
Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.
Все, кто поддержат проект до релиза, получат:
🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
➕ Доступ к закрытому бета-тесту
Поддержать 👉 https://planeta.ru/campaigns/easyoffer
Спасибо, что верите в этот проект 🙌
Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.
Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.
Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.
📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)
В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..
Тогда и пришла идея
А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.
Так родился easyoffer.
Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.
Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.
В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни
Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.
Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.
Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.
Все, кто поддержат проект до релиза, получат:
🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
➕ Доступ к закрытому бета-тесту
Поддержать 👉 https://planeta.ru/campaigns/easyoffer
Спасибо, что верите в этот проект 🙌
🤔2❤1
Задача: №44. Wildcard Matching
Сложность: hard
При наличии входных строк s и шаблона p реализуйте сопоставление шаблонов с подстановочными знаками с поддержкой "?" и "*", где:
- "?" соответствует любому отдельному символу.
- "*" соответствует любой последовательности символов (включая пустую последовательность).
Соответствие должно охватывать всю входную строку (не частичное).
Пример:
👨💻 Алгоритм:
1️⃣ Используем динамическое программирование, создаем матрицу dp для хранения промежуточных результатов.
2️⃣ Инициализируем dp[0][0] = True (пустая строка соответствует пустому шаблону).
3️⃣ Заполняем dp, учитывая, что "?" заменяет любой символ, а "*" может заменять любую последовательность символов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
При наличии входных строк s и шаблона p реализуйте сопоставление шаблонов с подстановочными знаками с поддержкой "?" и "*", где:
- "?" соответствует любому отдельному символу.
- "*" соответствует любой последовательности символов (включая пустую последовательность).
Соответствие должно охватывать всю входную строку (не частичное).
Пример:
Input: s = "adceb", p = "*a*b"
Output: true
class Solution:
def isMatch(self, s: str, p: str) -> bool:
m, n = len(s), len(p)
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[0][0] = True
for j in range(1, n + 1):
if p[j - 1] == '*':
dp[0][j] = dp[0][j - 1]
for i in range(1, m + 1):
for j in range(1, n + 1):
if p[j - 1] == s[i - 1] or p[j - 1] == '?':
dp[i][j] = dp[i - 1][j - 1]
elif p[j - 1] == '*':
dp[i][j] = dp[i - 1][j] or dp[i][j - 1]
return dp[m][n]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Задача: 1244. Design A Leaderboard
Сложность: medium
Разработайте класс Leaderboard, который содержит 3 функции: addScore(playerId, score): Обновляет таблицу лидеров, добавляя счет к счету данного игрока. Если в таблице лидеров нет игрока с таким id, добавьте его в таблицу лидеров с заданным счетом. top(K): Возвращает сумму очков K лучших игроков. reset(playerId): Сбрасывает счет игрока с заданным идентификатором в 0 (другими словами, стирает его из таблицы лидеров). Гарантируется, что игрок был добавлен в таблицу лидеров до вызова этой функции. Изначально таблица лидеров пуста.
Пример:
👨💻 Алгоритм:
1⃣ addScore(playerId, score):
Если игрок уже существует в таблице лидеров, добавляем к его текущему счету новое значение.
Если игрок не существует, добавляем его с заданным счетом.
2⃣ top(K):
Сортируем игроков по их счету в порядке убывания.
Возвращаем сумму очков K лучших игроков.
3⃣ reset(playerId):
Устанавливаем счет игрока в 0.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Разработайте класс Leaderboard, который содержит 3 функции: addScore(playerId, score): Обновляет таблицу лидеров, добавляя счет к счету данного игрока. Если в таблице лидеров нет игрока с таким id, добавьте его в таблицу лидеров с заданным счетом. top(K): Возвращает сумму очков K лучших игроков. reset(playerId): Сбрасывает счет игрока с заданным идентификатором в 0 (другими словами, стирает его из таблицы лидеров). Гарантируется, что игрок был добавлен в таблицу лидеров до вызова этой функции. Изначально таблица лидеров пуста.
Пример:
Input:
["Leaderboard","addScore","addScore","addScore","addScore","addScore","top","reset","reset","addScore","top"]
[[],[1,73],[2,56],[3,39],[4,51],[5,4],[1],[1],[2],[2,51],[3]]
Output:
[null,null,null,null,null,null,73,null,null,null,141]
Если игрок уже существует в таблице лидеров, добавляем к его текущему счету новое значение.
Если игрок не существует, добавляем его с заданным счетом.
Сортируем игроков по их счету в порядке убывания.
Возвращаем сумму очков K лучших игроков.
Устанавливаем счет игрока в 0.
from collections import defaultdict
class Leaderboard:
def __init__(self):
self.scores = defaultdict(int)
def addScore(self, playerId, score):
self.scores[playerId] += score
def top(self, K):
return sum(sorted(self.scores.values(), reverse=True)[:K])
def reset(self, playerId):
self.scores[playerId] = 0
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Задача: №21. Merge Two Sorted Lists
Сложность: easy
Вам даны заголовки двух отсортированных связанных списков list1 и list2. Объедините два списка в один отсортированный список. Список должен быть составлен путем сращивания узлов первых двух списков. Возвращает заголовок объединенного связанного списка.
Пример:
👨💻 Алгоритм:
1️⃣ Создать фиктивный узел для упрощения слияния.
2️⃣ Использовать указатель для поочередного добавления наименьшего элемента из двух списков.
3️⃣ Добавить оставшиеся элементы и вернуть заголовок объединенного списка.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам даны заголовки двух отсортированных связанных списков list1 и list2. Объедините два списка в один отсортированный список. Список должен быть составлен путем сращивания узлов первых двух списков. Возвращает заголовок объединенного связанного списка.
Пример:
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
class Solution:
def mergeTwoLists(self, l1, l2):
dummy = ListNode(0)
cur = dummy
while l1 and l2:
if l1.val <= l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
cur.next = l1 or l2
return dummy.next
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Задача: 834. Sum of Distances in Tree
Сложность: hard
Есть неориентированное связное дерево с n узлами, пронумерованными от 0 до n - 1, и n - 1 ребрами.
Вам даны целое число n и массив edges, где edges[i] = [ai, bi] указывает, что существует ребро между узлами ai и bi в дереве.
Верните массив answer длиной n, где answer[i] — это сумма расстояний между i-м узлом в дереве и всеми другими узлами.
Пример:
👨💻 Алгоритм:
1⃣ Постройте дерево и выполните обход в глубину (DFS) для расчета количества узлов в поддереве и суммы расстояний до всех узлов поддерева.
2⃣ На основе полученных данных рассчитайте сумму расстояний для корня дерева.
3⃣ Выполните второй обход в глубину (DFS) для корректировки суммы расстояний для каждого узла на основе суммы расстояний его родительского узла.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Есть неориентированное связное дерево с n узлами, пронумерованными от 0 до n - 1, и n - 1 ребрами.
Вам даны целое число n и массив edges, где edges[i] = [ai, bi] указывает, что существует ребро между узлами ai и bi в дереве.
Верните массив answer длиной n, где answer[i] — это сумма расстояний между i-м узлом в дереве и всеми другими узлами.
Пример:
Input: n = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]]
Output: [8,12,6,10,10,10]
Explanation: The tree is shown above.
We can see that dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5)
equals 1 + 1 + 2 + 2 + 2 = 8.
Hence, answer[0] = 8, and so on.
class Solution:
def sumOfDistancesInTree(self, N: int, edges: List[List[int]]) -> List[int]:
import collections
graph = collections.defaultdict(set)
for u, v in edges:
graph[u].add(v)
graph[v].add(u)
ans = [0] * N
count = [1] * N
def dfs(node=0, parent=None):
for neighbor in graph[node]:
if neighbor != parent:
dfs(neighbor, node)
count[node] += count[neighbor]
ans[node] += ans[neighbor] + count[neighbor]
def dfs2(node=0, parent=None):
for neighbor in graph[node]:
if neighbor != parent:
ans[neighbor] = ans[node] - count[neighbor] + N - count[neighbor]
dfs2(neighbor, node)
dfs()
dfs2()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 974. Subarray Sums Divisible by K
Сложность: medium
Дан целочисленный массив nums и целое число k. Верните количество непустых подмассивов, сумма которых делится на k.
Подмассив — это непрерывная часть массива.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и подготовка. Инициализируйте prefixMod = 0 для хранения остатка от суммы элементов до текущего индекса при делении на k. Инициализируйте result = 0 для хранения количества подмассивов, сумма которых делится на k. Инициализируйте массив modGroups длиной k, где modGroups[R] хранит количество подмассивов с остатком R. Установите modGroups[0] = 1.
2⃣ Итерирование по массиву. Для каждого элемента массива nums вычислите новый prefixMod как (prefixMod + nums[i] % k + k) % k, чтобы избежать отрицательных значений. Увеличьте result на значение modGroups[prefixMod], чтобы добавить количество подмассивов с текущим остатком. Увеличьте значение modGroups[prefixMod] на 1 для будущих совпадений.
3⃣ Возврат результата. Верните значение result, которое содержит количество подмассивов, сумма которых делится на k.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан целочисленный массив nums и целое число k. Верните количество непустых подмассивов, сумма которых делится на k.
Подмассив — это непрерывная часть массива.
Пример:
Input: nums = [4,5,0,-2,-3,1], k = 5
Output: 7
Explanation: There are 7 subarrays with a sum divisible by k = 5:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
class Solution:
def subarraysDivByK(self, nums: List[int], k: int) -> int:
prefixMod = 0
result = 0
modGroups = [0] * k
modGroups[0] = 1
for num in nums:
prefixMod = (prefixMod + num % k + k) % k
result += modGroups[prefixMod]
modGroups[prefixMod] += 1
return result
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 969. Pancake Sorting
Сложность: medium
Дан массив целых чисел arr, отсортируйте массив, выполняя серию переворотов блинов.
При одном перевороте блина мы выполняем следующие шаги:
Выбираем целое число k, где 1 <= k <= arr.length.
Переворачиваем подмассив arr[0...k-1] (индексация с 0).
Например, если arr = [3,2,1,4] и мы выполнили переворот блина, выбрав k = 3, мы переворачиваем подмассив [3,2,1], так что arr = [1,2,3,4] после переворота блина при k = 3.
Верните массив значений k, соответствующих последовательности переворотов блинов, которая сортирует arr. Любой допустимый ответ, который сортирует массив за количество переворотов не более чем 10 * arr.length, будет считаться правильным.
Пример:
👨💻 Алгоритм:
1⃣ Вдохновляясь пузырьковой сортировкой, начнем с реализации функции flip(list, k), которая выполняет переворот блина на префиксе list[0
] (в Python).
2⃣ Основной алгоритм выполняет цикл по значениям списка, начиная с наибольшего.
3⃣ На каждом этапе определяем значение для сортировки (назовем его value_to_sort), которое является числом, которое мы будем ставить на место на этом этапе. Затем находим индекс value_to_sort. Если value_to_sort еще не на своем месте, выполняем максимум два переворота блинов, как объяснено в интуиции. В конце этапа value_to_sort будет на своем месте.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел arr, отсортируйте массив, выполняя серию переворотов блинов.
При одном перевороте блина мы выполняем следующие шаги:
Выбираем целое число k, где 1 <= k <= arr.length.
Переворачиваем подмассив arr[0...k-1] (индексация с 0).
Например, если arr = [3,2,1,4] и мы выполнили переворот блина, выбрав k = 3, мы переворачиваем подмассив [3,2,1], так что arr = [1,2,3,4] после переворота блина при k = 3.
Верните массив значений k, соответствующих последовательности переворотов блинов, которая сортирует arr. Любой допустимый ответ, который сортирует массив за количество переворотов не более чем 10 * arr.length, будет считаться правильным.
Пример:
Input: arr = [3,2,4,1]
Output: [4,2,4,3]
Explanation:
We perform 4 pancake flips, with k values 4, 2, 4, and 3.
Starting state: arr = [3, 2, 4, 1]
After 1st flip (k = 4): arr = [1, 4, 2, 3]
After 2nd flip (k = 2): arr = [4, 1, 2, 3]
After 3rd flip (k = 4): arr = [3, 2, 1, 4]
After 4th flip (k = 3): arr = [1, 2, 3, 4], which is sorted.
] (в Python).
class Solution:
def pancakeSort(self, A):
ans = []
for value_to_sort in range(len(A), 0, -1):
index = self.find(A, value_to_sort)
if index == value_to_sort - 1:
continue
if index != 0:
ans.append(index + 1)
self.flip(A, index + 1)
ans.append(value_to_sort)
self.flip(A, value_to_sort)
return ans
def flip(self, sublist, k):
sublist[:k] = sublist[:k][::-1]
def find(self, a, target):
for i, num in enumerate(a):
if num == target:
return i
return -1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
Задача: 171. Excel Sheet Column Number
Сложность: easy
Дана строка
Пример:
👨💻 Алгоритм:
1️⃣ Создайте отображение букв алфавита и их соответствующих значений (начиная с 1).
2️⃣ Инициализируйте переменную-аккумулятор result.
3️⃣ Начиная справа налево, вычислите значение символа в
зависимости от его позиции и добавьте его к result.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дана строка
columnTitle, представляющая название столбца, как это отображается в Excel. Вернуть соответствующий номер столбца.Пример:
Input: columnTitle = "A"
Output: 1
зависимости от его позиции и добавьте его к result.
class Solution:
def titleToNumber(self, s: str) -> int:
result = 0
alpha_map = {chr(i + 65): i + 1 for i in range(26)}
n = len(s)
for i in range(n):
cur_char = s[n - 1 - i]
result += alpha_map[cur_char] * (26**i)
return result
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 190. Reverse Bits
Сложность: easy
Переверните биты заданного 32-битного беззнакового целого числа.
Пример:
👨💻 Алгоритм:
1️⃣ Итерируем по байтам целого числа, используя побитовую операцию И (n & 0xff) с маской 11111111, чтобы извлечь крайний правый байт числа.
2️⃣ Для каждого байта сначала переворачиваем биты внутри байта с помощью функции reverseByte(byte). Затем сдвигаем перевернутые биты на их окончательные позиции.
3️⃣ В функции reverseByte(byte) используем технику мемоизации, которая сохраняет результат функции и возвращает его непосредственно при последующих вызовах с тем же входным значением. Мемоизация — это компромисс между использованием памяти и объемом вычислений.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Переверните биты заданного 32-битного беззнакового целого числа.
Пример:
Input: n = 00000010100101000001111010011100
Output: 964176192 (00111001011110000010100101000000)
Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
Example 2:
import functools
class Solution:
def reverseBits(self, n: int) -> int:
ret, power = 0, 24
while n:
ret += self.reverseByte(n & 0xFF) << power
n = n >> 8
power -= 8
return ret
@functools.lru_cache(maxsize=256)
def reverseByte(self, byte):
return (byte * 0x0202020202 & 0x010884422010) % 1023
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Задача: 995. Minimum Number of K Consecutive Bit Flips
Сложность: hard
Дан бинарный массив nums и целое число k.
Операция переворота k-бит заключается в выборе подмассива длиной k из nums и одновременном изменении каждого 0 в подмассиве на 1 и каждого 1 в подмассиве на 0.
Верните минимальное количество k-битных переворотов, необходимых для того, чтобы в массиве не осталось 0. Если это невозможно, верните -1.
Подмассив - это непрерывная часть массива.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация переменных:
Создайте массив flip, чтобы отслеживать, сколько раз был перевернут каждый элемент.
Инициализируйте flips для отслеживания количества текущих переворотов.
2⃣ Перебор элементов массива:
Для каждого элемента определите, необходимо ли его переворачивать, учитывая текущее количество переворотов и значение в массиве.
Если нужно перевернуть, увеличьте счетчик переворотов и обновите массив flip.
3⃣ Проверка возможности выполнения задачи:
Если количество переворотов больше длины массива, верните -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан бинарный массив nums и целое число k.
Операция переворота k-бит заключается в выборе подмассива длиной k из nums и одновременном изменении каждого 0 в подмассиве на 1 и каждого 1 в подмассиве на 0.
Верните минимальное количество k-битных переворотов, необходимых для того, чтобы в массиве не осталось 0. Если это невозможно, верните -1.
Подмассив - это непрерывная часть массива.
Пример:
Input: nums = [0,1,0], k = 1
Output: 2
Explanation: Flip nums[0], then flip nums[2].
Создайте массив flip, чтобы отслеживать, сколько раз был перевернут каждый элемент.
Инициализируйте flips для отслеживания количества текущих переворотов.
Для каждого элемента определите, необходимо ли его переворачивать, учитывая текущее количество переворотов и значение в массиве.
Если нужно перевернуть, увеличьте счетчик переворотов и обновите массив flip.
Если количество переворотов больше длины массива, верните -1.
class Solution:
def minKBitFlips(self, nums: List[int], k: int) -> int:
n = len(nums)
flip = 0
flips = 0
flip_queue = [0] * n
for i in range(n):
if i >= k:
flip ^= flip_queue[i - k]
if nums[i] == flip:
if i + k > n:
return -1
flips += 1
flip ^= 1
flip_queue[i] = 1
return flips
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 999. Available Captures for Rook
Сложность: easy
Вам дана матрица 8 x 8, изображающая шахматную доску. На ней есть ровно одна белая ладья, представленная символом "R", некоторое количество белых слонов "B" и некоторое количество черных пешек "p". Пустые клетки обозначаются символом '.'. Ладья может перемещаться на любое количество клеток по горизонтали или вертикали (вверх, вниз, влево, вправо), пока не достигнет другой фигуры или края доски. Ладья атакует пешку, если она может переместиться на ее клетку за один ход. Примечание: Ладья не может перемещаться через другие фигуры, такие как слоны или пешки. Это означает, что ладья не может атаковать пешку, если путь ей преграждает другая фигура. Верните количество пешек, которые атакует белая ладья.
Пример:
👨💻 Алгоритм:
1⃣ Поиск ладьи:
Найдите координаты белой ладьи "R" на шахматной доске.
2⃣ Проверка направлений атаки:
Проверьте все четыре направления (влево, вправо, вверх, вниз) от позиции ладьи.
Перемещайтесь по каждому направлению до тех пор, пока не встретите другую фигуру или край доски.
3⃣ Подсчет атакованных пешек:
Если встреченная фигура - черная пешка "p", увеличьте счетчик атакованных пешек.
Если встреченная фигура - белый слон "B" или край доски, остановитесь в этом направлении.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам дана матрица 8 x 8, изображающая шахматную доску. На ней есть ровно одна белая ладья, представленная символом "R", некоторое количество белых слонов "B" и некоторое количество черных пешек "p". Пустые клетки обозначаются символом '.'. Ладья может перемещаться на любое количество клеток по горизонтали или вертикали (вверх, вниз, влево, вправо), пока не достигнет другой фигуры или края доски. Ладья атакует пешку, если она может переместиться на ее клетку за один ход. Примечание: Ладья не может перемещаться через другие фигуры, такие как слоны или пешки. Это означает, что ладья не может атаковать пешку, если путь ей преграждает другая фигура. Верните количество пешек, которые атакует белая ладья.
Пример:
Input: board = [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","R",".",".",".","p"],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 3
Найдите координаты белой ладьи "R" на шахматной доске.
Проверьте все четыре направления (влево, вправо, вверх, вниз) от позиции ладьи.
Перемещайтесь по каждому направлению до тех пор, пока не встретите другую фигуру или край доски.
Если встреченная фигура - черная пешка "p", увеличьте счетчик атакованных пешек.
Если встреченная фигура - белый слон "B" или край доски, остановитесь в этом направлении.
class Solution:
def numRookCaptures(self, board: List[List[str]]) -> int:
def count_pawns(x, y, dx, dy):
while 0 <= x < 8 and 0 <= y < 8:
if board[x][y] == 'B':
break
if board[x][y] == 'p':
return 1
x, y = x + dx, y + dy
return 0
for i in range(8):
for j in range(8):
if board[i][j] == 'R':
return (count_pawns(i, j, -1, 0) + count_pawns(i, j, 1, 0) +
count_pawns(i, j, 0, -1) + count_pawns(i, j, 0, 1))
return 0
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Задача: 331. Verify Preorder Serialization of a Binary Tree
Сложность: medium
Один из способов сериализации бинарного дерева — использование обхода в порядке предварительного прохода (preorder traversal). Когда мы встречаем ненулевой узел, мы записываем значение узла. Если это нулевой узел, мы записываем его с использованием специального значения, такого как '#'.
Дана строка, содержащая значения, разделенные запятыми, представляющие предварительный обход дерева (preorder). Верните true, если это правильная сериализация предварительного обхода бинарного дерева.
Гарантируется, что каждое значение в строке, разделенное запятыми, должно быть либо целым числом, либо символом '#', представляющим нулевой указатель.
Вы можете предположить, что формат ввода всегда действителен.
Например, он никогда не может содержать две последовательные запятые, такие как "1,,3".
Примечание: Вам не разрешено восстанавливать дерево.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и разбор строки:
Инициализируйте переменную slots значением 1, представляющую количество доступных слотов.
Разделите строку по запятым, чтобы получить массив элементов.
2⃣ Итерация по элементам и проверка:
Перебирайте каждый элемент массива. Для каждого элемента уменьшайте количество слотов на 1.
Если количество слотов становится отрицательным, верните false, так как это означает неправильную сериализацию.
Если элемент не равен '#', увеличьте количество слотов на 2, так как непустой узел создает два новых слота.
3⃣ Проверка завершения:
После итерации по всем элементам проверьте, равно ли количество слотов 0. Если да, верните true, в противном случае false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Один из способов сериализации бинарного дерева — использование обхода в порядке предварительного прохода (preorder traversal). Когда мы встречаем ненулевой узел, мы записываем значение узла. Если это нулевой узел, мы записываем его с использованием специального значения, такого как '#'.
Дана строка, содержащая значения, разделенные запятыми, представляющие предварительный обход дерева (preorder). Верните true, если это правильная сериализация предварительного обхода бинарного дерева.
Гарантируется, что каждое значение в строке, разделенное запятыми, должно быть либо целым числом, либо символом '#', представляющим нулевой указатель.
Вы можете предположить, что формат ввода всегда действителен.
Например, он никогда не может содержать две последовательные запятые, такие как "1,,3".
Примечание: Вам не разрешено восстанавливать дерево.
Пример:
Input: preorder = "9,3,4,#,#,1,#,#,2,#,6,#,#"
Output: true
Инициализируйте переменную slots значением 1, представляющую количество доступных слотов.
Разделите строку по запятым, чтобы получить массив элементов.
Перебирайте каждый элемент массива. Для каждого элемента уменьшайте количество слотов на 1.
Если количество слотов становится отрицательным, верните false, так как это означает неправильную сериализацию.
Если элемент не равен '#', увеличьте количество слотов на 2, так как непустой узел создает два новых слота.
После итерации по всем элементам проверьте, равно ли количество слотов 0. Если да, верните true, в противном случае false.
class Solution:
def isValidSerialization(self, preorder: str) -> bool:
slots = 1
nodes = preorder.split(',')
for node in nodes:
slots -= 1
if slots < 0:
return False
if node != '#':
slots += 2
return slots == 0
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 63. Unique Paths II
Сложность: medium
Вам дана матрица размером m на n, содержащая целые числа. Робот находится в начальный момент в верхнем левом углу (то есть в ячейке grid[0][0]). Робот пытается добраться до нижнего правого угла (то есть в ячейку grid[m - 1][n - 1]). Робот может двигаться только вниз или вправо в любой момент времени.
Препятствия и свободные пространства отмечены в матрице как 1 и 0 соответственно. Путь, который проходит робот, не может включать клетки, которые являются препятствиями.
Верните количество возможных уникальных путей, по которым робот может добраться до нижнего правого угла.
Тестовые примеры сгенерированы таким образом, что ответ будет не более 2 * 10^9.
Пример:
👨💻 Алгоритм:
1️⃣ Если первая ячейка, то есть obstacleGrid[0,0], содержит 1, это означает, что в первой ячейке есть препятствие. Следовательно, робот не сможет сделать ни одного хода, и мы должны вернуть количество возможных путей как 0. Если же obstacleGrid[0,0] изначально равно 0, мы устанавливаем его равным 1 и продолжаем.
2️⃣ Итерация по первой строке. Если ячейка изначально содержит 1, это означает, что текущая ячейка имеет препятствие и не должна учитываться в каком-либо пути. Следовательно, значение этой ячейки устанавливается равным 0. В противном случае, устанавливаем его равным значению предыдущей ячейки, то есть obstacleGrid[i,j] = obstacleGrid[i,j-1]. Повторяем аналогичные действия для первого столбца.
3️⃣ Далее, итерация по массиву начиная с ячейки obstacleGrid[1,1]. Если ячейка изначально не содержит препятствий, то количество способов добраться до этой ячейки будет равно сумме количества способов добраться до ячейки над ней и количества способов добраться до ячейки слева от неё, то есть obstacleGrid[i,j] = obstacleGrid[i-1,j] + obstacleGrid[i,j-1]. Если в ячейке есть препятствие, устанавливаем её значение равным 0 и продолжаем. Это делается для того, чтобы она не учитывалась в других путях.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана матрица размером m на n, содержащая целые числа. Робот находится в начальный момент в верхнем левом углу (то есть в ячейке grid[0][0]). Робот пытается добраться до нижнего правого угла (то есть в ячейку grid[m - 1][n - 1]). Робот может двигаться только вниз или вправо в любой момент времени.
Препятствия и свободные пространства отмечены в матрице как 1 и 0 соответственно. Путь, который проходит робот, не может включать клетки, которые являются препятствиями.
Верните количество возможных уникальных путей, по которым робот может добраться до нижнего правого угла.
Тестовые примеры сгенерированы таким образом, что ответ будет не более 2 * 10^9.
Пример:
Input: obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
Output: 2
Explanation: There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right
class Solution(object):
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m = len(obstacleGrid)
n = len(obstacleGrid[0])
if obstacleGrid[0][0] == 1:
return 0
obstacleGrid[0][0] = 1
for i in range(1, m):
obstacleGrid[i][0] = int(
obstacleGrid[i][0] == 0 and obstacleGrid[i - 1][0] == 1
)
for j in range(1, n):
obstacleGrid[0][j] = int(
obstacleGrid[0][j] == 0 and obstacleGrid[0][j - 1] == 1
)
for i in range(1, m):
for j in range(1, n):
if obstacleGrid[i][j] == 0:
obstacleGrid[i][j] = (
obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1]
)
else:
obstacleGrid[i][j] = 0
return obstacleGrid[m - 1][n - 1]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Forwarded from easyoffer
⏳ Осталось всего 14 дней до завершения краудфандинга
Сейчас самое подходящее время подключиться, если вы ждали или откладывали:
Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
➕ Бета-доступ к EasyOffer 2.0 (конец мая)
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
Сейчас самое подходящее время подключиться, если вы ждали или откладывали:
Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
➕ Бета-доступ к EasyOffer 2.0 (конец мая)
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
❤1
Задача: 240. Search a 2D Matrix II
Сложность: medium
Напишите эффективный алгоритм, который ищет значение target в матрице целых чисел размером m на n. У этой матрицы есть следующие свойства:
Целые числа в каждой строке отсортированы по возрастанию слева направо.
Целые числа в каждом столбце отсортированы по возрастанию сверху вниз.
Пример:
👨💻 Алгоритм:
1️⃣ Проверка матрицы: Перед началом поиска убедитесь, что матрица не пуста и не содержит null.
2️⃣ Итерация по диагоналям: Итерируйте по диагоналям матрицы, используя инвариант отсортированности срезов строк и столбцов, начиная с текущей позиции (строка, столбец). Для каждого такого среза используйте бинарный поиск для нахождения целевого значения.
3️⃣ Бинарный поиск и завершение: Продолжайте бинарный поиск до тех пор, пока не исчерпаете все диагонали (в этом случае возвращается False) или пока не найдете целевое значение (в этом случае возвращается True). Функция бинарного поиска должна уметь работать как с рядами, так и с колонками матрицы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Напишите эффективный алгоритм, который ищет значение target в матрице целых чисел размером m на n. У этой матрицы есть следующие свойства:
Целые числа в каждой строке отсортированы по возрастанию слева направо.
Целые числа в каждом столбце отсортированы по возрастанию сверху вниз.
Пример:
Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
Output: true
class Solution:
def binarySearch(self, matrix, target, start, vertical):
lo = start
hi = len(matrix[0]) - 1 if vertical else len(matrix) - 1
while hi >= lo:
mid = (lo + hi) // 2
if vertical:
if matrix[start][mid] < target:
lo = mid + 1
elif matrix[start][mid] > target:
hi = mid - 1
else:
return True
else:
if matrix[mid][start] < target:
lo = mid + 1
elif matrix[mid][start] > target:
hi = mid - 1
else:
return True
return False
def searchMatrix(self, matrix, target):
if not matrix or not matrix[0]:
return False
shorterDim = min(len(matrix), len(matrix[0]))
for i in range(shorterDim):
if self.binarySearch(matrix, target, i, True) or self.binarySearch(matrix, target, i, False):
return True
return False
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🤔1
Задача: 1048. Longest String Chain
Сложность: easy
Вам дан массив слов, каждое из которых состоит из строчных английских букв. СловоА является предшественником словаВ тогда и только тогда, когда мы можем вставить ровно одну букву в любое место словаА, не меняя порядка остальных символов, чтобы оно стало равно словуВ.
Например, "abc" является предшественником "abac", а "cba" не является предшественником "bcad". Цепочка слов - это последовательность слов [word1, word2, ..., wordk] с k >= 1, где word1 является предшественником word2, word2 является предшественником word3 и так далее. Одиночное слово тривиально является цепочкой слов с k == 1. Верните длину самой длинной возможной цепочки слов со словами, выбранными из заданного списка слов.
Пример:
👨💻 Алгоритм:
1⃣ Отсортируй список слов по длине.
2⃣ Используй динамическое программирование для вычисления длины самой длинной цепочки для каждого слова.
3⃣ Верни максимальную длину среди всех цепочек.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам дан массив слов, каждое из которых состоит из строчных английских букв. СловоА является предшественником словаВ тогда и только тогда, когда мы можем вставить ровно одну букву в любое место словаА, не меняя порядка остальных символов, чтобы оно стало равно словуВ.
Например, "abc" является предшественником "abac", а "cba" не является предшественником "bcad". Цепочка слов - это последовательность слов [word1, word2, ..., wordk] с k >= 1, где word1 является предшественником word2, word2 является предшественником word3 и так далее. Одиночное слово тривиально является цепочкой слов с k == 1. Верните длину самой длинной возможной цепочки слов со словами, выбранными из заданного списка слов.
Пример:
Input: words = ["a","b","ba","bca","bda","bdca"]
Output: 4
def longestStrChain(words):
words.sort(key=len)
dp = {}
longest_chain = 1
for word in words:
dp[word] = 1
for i in range(len(word)):
predecessor = word[:i] + word[i+1:]
if predecessor in dp:
dp[word] = max(dp[word], dp[predecessor] + 1)
longest_chain = max(longest_chain, dp[word])
return longest_chain
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1🔥1