Задача: 1197. Minimum Knight Moves
Сложность: medium
На бесконечной шахматной доске с координатами от -бесконечности до +бесконечности у вас есть конь на клетке [0, 0].
У коня есть 8 возможных ходов. Каждый ход представляет собой два квадрата в кардинальном направлении, затем один квадрат в ортогональном направлении.
Верните минимальное количество шагов, необходимых для перемещения коня на клетку [x, y]. Гарантируется, что ответ существует.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация структур данных:
Инициализируйте две очереди для хранения координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
Инициализируйте две карты для хранения посещенных координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
2⃣ Реализация двунаправленного поиска в ширину (BFS):
Выполняйте шаги из очередей, расширяя круги поиска как от начальной, так и от конечной точки.
Если круги пересекаются, возвращайте сумму расстояний до точки пересечения.
3⃣ Расширение кругов поиска:
Для каждой текущей точки из очередей расширяйте круг поиска по всем возможным ходам коня.
Обновляйте расстояния и добавляйте новые точки в очереди, если они еще не были посещены.
Увеличивайте units на значение, извлеченное из кучи.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
На бесконечной шахматной доске с координатами от -бесконечности до +бесконечности у вас есть конь на клетке [0, 0].
У коня есть 8 возможных ходов. Каждый ход представляет собой два квадрата в кардинальном направлении, затем один квадрат в ортогональном направлении.
Верните минимальное количество шагов, необходимых для перемещения коня на клетку [x, y]. Гарантируется, что ответ существует.
Пример:
Input: x = 5, y = 5
Output: 4
Explanation: [0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]
Инициализируйте две очереди для хранения координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
Инициализируйте две карты для хранения посещенных координат и расстояний: одну для движения от начальной точки, другую — от конечной точки.
Выполняйте шаги из очередей, расширяя круги поиска как от начальной, так и от конечной точки.
Если круги пересекаются, возвращайте сумму расстояний до точки пересечения.
Для каждой текущей точки из очередей расширяйте круг поиска по всем возможным ходам коня.
Обновляйте расстояния и добавляйте новые точки в очереди, если они еще не были посещены.
Увеличивайте units на значение, извлеченное из кучи.
from collections import deque
class Solution:
def minKnightMoves(self, x: int, y: int) -> int:
offsets = [(1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1), (-2, 1), (-1, 2)]
origin_queue = deque([(0, 0, 0)])
origin_distance = {"0,0": 0}
target_queue = deque([(x, y, 0)])
target_distance = {f"{x},{y}": 0}
while True:
ox, oy, od = origin_queue.popleft()
origin_key = f"{ox},{oy}"
if origin_key in target_distance:
return od + target_distance[origin_key]
tx, ty, td = target_queue.popleft()
target_key = f"{tx},{ty}"
if target_key in origin_distance:
return td + origin_distance[target_key]
for dx, dy in offsets:
next_origin = (ox + dx, oy + dy, od + 1)
next_origin_key = f"{next_origin[0]},{next_origin[1]}"
if next_origin_key not in origin_distance:
origin_queue.append(next_origin)
origin_distance[next_origin_key] = next_origin[2]
next_target = (tx + dx, ty + dy, td + 1)
next_target_key = f"{next_target[0]},{next_target[1]}"
if next_target_key not in target_distance:
target_queue.append(next_target)
target_distance[next_target_key] = next_target[2]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🤯1
Задача: 922. Sort Array By Parity II
Сложность: medium
Дан массив целых чисел nums, половина целых чисел в нем нечетные, а другая половина - четные. Отсортируйте массив так, чтобы во всех случаях, когда nums[i] нечетный, i был нечетным, а во всех случаях, когда nums[i] четный, i был четным. Верните любой массив ответов, удовлетворяющий этому условию.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать два указателя even_idx и odd_idx для отслеживания позиций четных и нечетных индексов соответственно.
2⃣ Пройти по массиву nums и для каждого элемента:
Если элемент четный, поместить его на позицию even_idx и увеличить even_idx на 2.
Если элемент нечетный, поместить его на позицию odd_idx и увеличить odd_idx на 2.
3⃣ Вернуть отсортированный массив.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел nums, половина целых чисел в нем нечетные, а другая половина - четные. Отсортируйте массив так, чтобы во всех случаях, когда nums[i] нечетный, i был нечетным, а во всех случаях, когда nums[i] четный, i был четным. Верните любой массив ответов, удовлетворяющий этому условию.
Пример:
Input: nums = [4,2,5,7]
Output: [4,5,2,7]
Если элемент четный, поместить его на позицию even_idx и увеличить even_idx на 2.
Если элемент нечетный, поместить его на позицию odd_idx и увеличить odd_idx на 2.
def sortArrayByParityII(nums):
result = [0] * len(nums)
even_idx, odd_idx = 0, 1
for num in nums:
if num % 2 == 0:
result[even_idx] = num
even_idx += 2
else:
result[odd_idx] = num
odd_idx += 2
return result
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1🔥1
Задача: 913. Cat and Mouse
Сложность: hard
В игру на неориентированном графе играют два игрока, Мышь и Кот, которые чередуются по очереди. Граф задан следующим образом: graph[a] - это список всех вершин b, таких, что ab является ребром графа. Мышь начинает в вершине 1 и идет первой, Кот начинает в вершине 2 и идет второй, а в вершине 0 находится дыра. Во время хода каждого игрока он должен пройти по одному ребру графа, которое встречает его местоположение.Например, если Мышь находится в узле 1, она должна добраться до любого узла графа[1]. Кроме того, Кошке запрещено добираться до Дыры (узел 0). Затем игра может закончиться тремя способами: если Кошка занимает тот же узел, что и Мышь, Кошка побеждает. Если Мышь достигает Дыры, Мышь побеждает. Если позиция повторяется (т.е, игроки находятся в той же позиции, что и в предыдущий ход, и сейчас очередь того же игрока двигаться), то игра считается ничейной. Учитывая граф и предполагая, что оба игрока играют оптимально, верните 1, если в игре победила мышь, 2, если в игре победила кошка, или 0, если в игре ничья.
Пример:
👨💻 Алгоритм:
1⃣ Использовать динамическое программирование с мемоизацией для хранения результатов игры для каждой комбинации позиций мыши, кота и текущего игрока.
2⃣ Проверить три условия окончания игры:
Мышь достигает дырки (победа мыши).
Кот достигает мыши (победа кота).
Позиция повторяется (ничья).
3⃣ Использовать BFS (поиск в ширину) для определения результатов игры, начиная с конечных состояний и работая назад.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
В игру на неориентированном графе играют два игрока, Мышь и Кот, которые чередуются по очереди. Граф задан следующим образом: graph[a] - это список всех вершин b, таких, что ab является ребром графа. Мышь начинает в вершине 1 и идет первой, Кот начинает в вершине 2 и идет второй, а в вершине 0 находится дыра. Во время хода каждого игрока он должен пройти по одному ребру графа, которое встречает его местоположение.Например, если Мышь находится в узле 1, она должна добраться до любого узла графа[1]. Кроме того, Кошке запрещено добираться до Дыры (узел 0). Затем игра может закончиться тремя способами: если Кошка занимает тот же узел, что и Мышь, Кошка побеждает. Если Мышь достигает Дыры, Мышь побеждает. Если позиция повторяется (т.е, игроки находятся в той же позиции, что и в предыдущий ход, и сейчас очередь того же игрока двигаться), то игра считается ничейной. Учитывая граф и предполагая, что оба игрока играют оптимально, верните 1, если в игре победила мышь, 2, если в игре победила кошка, или 0, если в игре ничья.
Пример:
Input: graph = [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
Output: 0
Мышь достигает дырки (победа мыши).
Кот достигает мыши (победа кота).
Позиция повторяется (ничья).
from collections import deque
def catMouseGame(graph):
n = len(graph)
DRAW, MOUSE, CAT = 0, 1, 2
dp = [[[DRAW] * 2 for _ in range(n)] for _ in range(n)]
queue = deque()
for i in range(1, n):
dp[0][i][0] = MOUSE
dp[0][i][1] = MOUSE
dp[i][i][0] = CAT
dp[i][i][1] = CAT
queue.append((0, i, 0, MOUSE))
queue.append((0, i, 1, MOUSE))
queue.append((i, i, 0, CAT))
queue.append((i, i, 1, CAT))
def parents(mouse, cat, turn):
if turn == 1:
for m in graph[mouse]:
yield (m, cat, 0)
else:
for c in graph[cat]:
if c > 0:
yield (mouse, c, 1)
while queue:
mouse, cat, turn, winner = queue.popleft()
for m, c, t in parents(mouse, cat, turn):
if dp[m][c][t] == DRAW:
if t == 0 and winner == MOUSE or t == 1 and winner == CAT:
dp[m][c][t] = winner
queue.append((m, c, t, winner))
else:
degrees = sum(1 for p in parents(m, c, t))
if degrees == 0:
dp[m][c][t] = winner
queue.append((m, c, t, winner))
return dp[1][2][0]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Forwarded from easyoffer
🎉 Краудфандинг easyoffer 2.0 стартовал!
Друзья, с этого момента вы можете поддержать проект и получить существенный бонус:
🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
➕ Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)
Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Друзья, с этого момента вы можете поддержать проект и получить существенный бонус:
🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
➕ Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)
Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
❤1
Forwarded from easyoffer
Я поставил целью сбора скромные 300 тыс. рублей, но ребята, вы накидали больше млн. всего за 1 день. Это просто невероятно!
Благодаря вашей поддержке, я смогу привлечь еще больше людей для разработки сайта и обработки собеседований. Ваш вклад сделает проект качественнее и ускорит его выход! Огромное вам спасибо!
Краудфандинг будет продолжаться еще 31 день и все кто поддержать проект сейчас, до его выхода, смогут получить:
🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
➕ Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)
Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer
Огромное спасибо за вашу поддержку! 🤝
Благодаря вашей поддержке, я смогу привлечь еще больше людей для разработки сайта и обработки собеседований. Ваш вклад сделает проект качественнее и ускорит его выход! Огромное вам спасибо!
Краудфандинг будет продолжаться еще 31 день и все кто поддержать проект сейчас, до его выхода, смогут получить:
🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
➕ Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)
Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer
Огромное спасибо за вашу поддержку! 🤝
❤1
Задача: 1436. Destination City
Сложность: easy
Дан массив paths, где paths[i] = [cityAi, cityBi] означает, что существует прямой путь из cityAi в cityBi. Вернуть конечный город, то есть город, из которого нет пути в другой город.
Гарантируется, что граф путей образует линию без циклов, поэтому будет ровно один конечный город.
Пример:
👨💻 Алгоритм:
1⃣ Для каждого города cityBi в paths проверьте, является ли он кандидатом на конечный город.
2⃣ Для каждого кандидата проверьте, нет ли пути, ведущего из него (cityAi == candidate).
3⃣ Верните город, который не имеет исходящих путей.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан массив paths, где paths[i] = [cityAi, cityBi] означает, что существует прямой путь из cityAi в cityBi. Вернуть конечный город, то есть город, из которого нет пути в другой город.
Гарантируется, что граф путей образует линию без циклов, поэтому будет ровно один конечный город.
Пример:
Input: paths = [["London","New York"],["New York","Lima"],["Lima","Sao Paulo"]]
Output: "Sao Paulo"
Explanation: Starting at "London" city you will reach "Sao Paulo" city which is the destination city. Your trip consist of: "London" -> "New York" -> "Lima" -> "Sao Paulo".
class Solution:
def destCity(self, paths: List[List[str]]) -> str:
for path in paths:
candidate = path[1]
good = True
for p in paths:
if p[0] == candidate:
good = False
break
if good:
return candidate
return ""
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1
Задача: 67. Add Binary
Сложность: easy
Даны две двоичные строки a и b. Верните их сумму в виде двоичной строки.
Пример:
👨💻 Алгоритм:
1️⃣ Начните с переноса carry = 0. Если в числе a наименьший бит равен 1, добавьте 1 к carry. То же самое относится к числу b: если в числе b наименьший бит равен 1, добавьте 1 к carry. В этот момент carry для наименьшего бита может быть равен 0 (00), 1 (01) или 2 (10).
2️⃣ Теперь добавьте наименьший бит carry к ответу и перенесите старший бит carry на следующий порядковый бит.
3️⃣ Повторяйте те же шаги снова и снова, пока не будут использованы все биты в a и b. Если остаётся ненулевой carry, добавьте его. Теперь переверните строку ответа, и задача выполнена.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны две двоичные строки a и b. Верните их сумму в виде двоичной строки.
Пример:
Input: a = "11", b = "1"
Output: "100"
class Solution:
def addBinary(self, a, b) -> str:
n = max(len(a), len(b))
a, b = a.zfill(n), b.zfill(n)
carry = 0
answer = []
for i in range(n - 1, -1, -1):
if a[i] == "1":
carry += 1
if b[i] == "1":
carry += 1
if carry % 2 == 1:
answer.append("1")
else:
answer.append("0")
carry //= 2
if carry == 1:
answer.append("1")
answer.reverse()
return "".join(answer)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🔥1
Задача: 1102. Path With Maximum Minimum Value
Сложность: medium
Дана целочисленная матрица grid размером m x n. Верните максимальное значение пути, начинающегося в (0, 0) и заканчивающегося в (m - 1, n - 1), двигаясь в 4 кардинальных направлениях.
Значение пути определяется минимальным числом на этом пути.
Пример:
👨💻 Алгоритм:
1⃣ Начните с оценки curScore = min(grid[0][0], grid[m-1][n-1]), где m и n - общее количество строк и столбцов входной матрицы.
2⃣ Выполните BFS на матрице и проверьте, существует ли путь, где все значения больше или равны curScore:
Используйте очередь (deque) для хранения всех непосещенных ячеек со значением, большим или равным curScore.
Извлекайте ячейку из начала очереди, проверяйте, есть ли у нее непосещенные соседние ячейки, и добавляйте их в конец очереди.
Если успешно достигли правой нижней ячейки, значит путь существует.
Если очередь опустела до достижения правой нижней ячейки, пути не существует.
3⃣ Если пути не существует, что означает, что curScore слишком велик, уменьшите его на 1 и повторите шаг 2.
В противном случае, верните curScore как ответ.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана целочисленная матрица grid размером m x n. Верните максимальное значение пути, начинающегося в (0, 0) и заканчивающегося в (m - 1, n - 1), двигаясь в 4 кардинальных направлениях.
Значение пути определяется минимальным числом на этом пути.
Пример:
Input: grid = [[5,4,5],[1,2,6],[7,4,6]]
Output: 4
Explanation: The path with the maximum score is highlighted in yellow.
Используйте очередь (deque) для хранения всех непосещенных ячеек со значением, большим или равным curScore.
Извлекайте ячейку из начала очереди, проверяйте, есть ли у нее непосещенные соседние ячейки, и добавляйте их в конец очереди.
Если успешно достигли правой нижней ячейки, значит путь существует.
Если очередь опустела до достижения правой нижней ячейки, пути не существует.
В противном случае, верните curScore как ответ.
from collections import deque
class Solution:
def maximumMinimumPath(self, grid: List[List[int]]) -> int:
def pathExists(curScore):
R, C = len(grid), len(grid[0])
visited = [[False] * C for _ in range(R)]
dq = deque([(0, 0)])
visited[0][0] = True
def push(row, col):
if 0 <= row < R and 0 <= col < C and not visited[row][col] and grid[row][col] >= curScore:
dq.append((row, col))
visited[row][col] = True
while dq:
curRow, curCol = dq.popleft()
if curRow == R - 1 and curCol == C - 1:
return True
for dr, dc in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
push(curRow + dr, curCol + dc)
return False
curScore = min(grid[0][0], grid[-1][-1])
while curScore >= 0:
if pathExists(curScore):
return curScore
curScore -= 1
return -1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 996. Number of Squareful Arrays
Сложность: hard
Массив является квадратным, если сумма каждой пары соседних элементов является совершенным квадратом. Если задан целочисленный массив nums, верните количество перестановок nums, которые являются квадратными. Две перестановки perm1 и perm2 различны, если существует некоторый индекс i такой, что perm1[i] != perm2[i].
Пример:
👨💻 Алгоритм:
1⃣ Генерация перестановок:
Сгенерируйте все возможные перестановки массива nums.
Для каждой перестановки проверьте, является ли она квадратной.
2⃣ Проверка квадратности:
Для каждой перестановки проверьте, является ли сумма каждой пары соседних элементов совершенным квадратом.
Для этого используйте функцию для проверки, является ли число совершенным квадратом.
3⃣ Подсчет квадратных перестановок:
Подсчитайте количество перестановок, которые являются квадратными, и верните это значение.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Массив является квадратным, если сумма каждой пары соседних элементов является совершенным квадратом. Если задан целочисленный массив nums, верните количество перестановок nums, которые являются квадратными. Две перестановки perm1 и perm2 различны, если существует некоторый индекс i такой, что perm1[i] != perm2[i].
Пример:
Input: nums = [1,17,8]
Output: 2
Сгенерируйте все возможные перестановки массива nums.
Для каждой перестановки проверьте, является ли она квадратной.
Для каждой перестановки проверьте, является ли сумма каждой пары соседних элементов совершенным квадратом.
Для этого используйте функцию для проверки, является ли число совершенным квадратом.
Подсчитайте количество перестановок, которые являются квадратными, и верните это значение.
from itertools import permutations
import math
class Solution:
def numSquarefulPerms(self, nums: List[int]) -> int:
def isPerfectSquare(x):
return int(math.isqrt(x)) ** 2 == x
def isSquareful(perm):
for i in range(len(perm) - 1):
if not isPerfectSquare(perm[i] + perm[i + 1]):
return False
return True
perms = set(permutations(nums))
count = sum(1 for perm in perms if isSquareful(perm))
return count
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Задача: 1213. Intersection of Three Sorted Arrays
Сложность: easy
Даны три целочисленных массива arr1, arr2 и arr3, отсортированных в строго возрастающем порядке. Верните отсортированный массив, содержащий только те целые числа, которые присутствуют во всех трех массивах.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте counter как TreeMap для записи чисел, которые появляются в трех массивах, и количество их появлений.
2⃣ Пройдитесь по массивам arr1, arr2 и arr3, чтобы посчитать частоты появления элементов.
3⃣ Итерация через counter, чтобы найти числа, которые появляются три раза, и вернуть их в виде отсортированного массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны три целочисленных массива arr1, arr2 и arr3, отсортированных в строго возрастающем порядке. Верните отсортированный массив, содержащий только те целые числа, которые присутствуют во всех трех массивах.
Пример:
Input: arr1 = [1,2,3,4,5], arr2 = [1,2,5,7,9], arr3 = [1,3,4,5,8]
Output: [1,5]
Explanation: Only 1 and 5 appeared in the three arrays.
class Solution:
def arraysIntersection(self, arr1, arr2, arr3):
from collections import Counter
counter = Counter(arr1) + Counter(arr2) + Counter(arr3)
return [num for num, freq in counter.items() if freq == 3]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 1242. Web Crawler Multithreaded
Сложность: medium
Учитывая URL startUrl и интерфейс HtmlParser, реализуйте многопоточный веб-краулер, который будет просматривать все ссылки, находящиеся под тем же именем хоста, что и startUrl. Верните все URL, полученные вашим веб-краулером, в любом порядке.
Ваш краулер должен: Начинать со страницы: startUrl Вызывать HtmlParser.getUrls(url), чтобы получить все URL с веб-страницы данного URL. Не просматривать одну и ту же ссылку дважды. Исследовать только те ссылки, которые находятся под тем же именем хоста, что и startUrl.
Пример:
👨💻 Алгоритм:
1⃣ Извлечь имя хоста из startUrl.
Использовать многопоточность для обработки URL-адресов.
2⃣ Хранить посещенные URL-адреса, чтобы избежать повторного посещения.
3⃣ Использовать HtmlParser для получения URL-адресов с веб-страниц.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Учитывая URL startUrl и интерфейс HtmlParser, реализуйте многопоточный веб-краулер, который будет просматривать все ссылки, находящиеся под тем же именем хоста, что и startUrl. Верните все URL, полученные вашим веб-краулером, в любом порядке.
Ваш краулер должен: Начинать со страницы: startUrl Вызывать HtmlParser.getUrls(url), чтобы получить все URL с веб-страницы данного URL. Не просматривать одну и ту же ссылку дважды. Исследовать только те ссылки, которые находятся под тем же именем хоста, что и startUrl.
Пример:
Input:
urls = [
"http://news.yahoo.com",
"http://news.yahoo.com/news",
"http://news.yahoo.com/news/topics/",
"http://news.google.com",
"http://news.yahoo.com/us"
]
edges = [[2,0],[2,1],[3,2],[3,1],[0,4]]
startUrl = "http://news.yahoo.com/news/topics/"
Output: [
"http://news.yahoo.com",
"http://news.yahoo.com/news",
"http://news.yahoo.com/news/topics/",
"http://news.yahoo.com/us"
]
Использовать многопоточность для обработки URL-адресов.
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urlparse
import threading
class HtmlParser:
def getUrls(self, url: str) -> [str]:
pass
def extract_hostname(url):
parsed_url = urlparse(url)
return parsed_url.netloc
def crawl(startUrl, htmlParser):
hostname = extract_hostname(startUrl)
visited = set()
lock = threading.Lock()
def visit(url):
if extract_hostname(url) == hostname:
with lock:
if url not in visited:
visited.add(url)
for next_url in htmlParser.getUrls(url):
executor.submit(visit, next_url)
with ThreadPoolExecutor(max_workers=10) as executor:
executor.submit(visit, startUrl)
return list(visited)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Forwarded from Идущий к IT
Привет ребята, мне на easyoffer.ru нужен:
🐍 Middle/Senior Python Developer
Стек:
DRF, PostgreSQL, Redis, Celery, Docker, Sentry
Задачи:
🟠 Разработка и поддержка REST API для новых фичей
🟠 Интеграция с веб-сервисами и внешними API
🟠 Подключение и поддержка платежных систем
🟠 Написание юнит- и интеграционных тестов
🟠 Оптимизация производительности и масштабирование
🟠 Взаимодействие с ML-моделями — будет плюсом
Ожидания:
🟠 2+ лет опыта DRF
🟠 Опыт интеграций платежных систем
🟠 Опыт работы с PostgreSQL, Celery, Redis, Docker
🟠 Умение проектировать архитектуру REST-API
🟠 Ответственный подход к качеству кода и тестированию
Опыт в стартапах и небольших командах будет плюсом
Условия:
– Частичная занятость (2-3 часа в день)
– Удаленная работа
– Свободный график
– Почасовая оплата
✈ Если вас заинтересовала вакансия, напишите мне @kivaiko
1. Резюме
2. Ссылку на github
3. Комфортную ставку за час
🐍 Middle/Senior Python Developer
Стек:
DRF, PostgreSQL, Redis, Celery, Docker, Sentry
Задачи:
Ожидания:
Опыт в стартапах и небольших командах будет плюсом
Условия:
– Частичная занятость (2-3 часа в день)
– Удаленная работа
– Свободный график
– Почасовая оплата
1. Резюме
2. Ссылку на github
3. Комфортную ставку за час
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 1087. Brace Expansion
Сложность: medium
Дан список оценок различных студентов, items, где items[i] = [IDi, scorei] представляет собой одну оценку студента с идентификатором IDi. Вычислите среднее значение пяти лучших оценок каждого студента.
Верните ответ в виде массива пар result, где result[j] = [IDj, topFiveAveragej] представляет студента с идентификатором IDj и его среднее значение пяти лучших оценок. Отсортируйте result по IDj в порядке возрастания.
Среднее значение пяти лучших оценок студента вычисляется путем сложения его пяти лучших оценок и деления на 5 с использованием целочисленного деления.
Пример:
👨💻 Алгоритм:
1⃣ Вызовите функцию findAllWords(String, Integer) с данной строкой s и значением startPos равным 0. startPos представляет текущую позицию в строке s. Если строка, которую нужно рассмотреть, пуста (startPos == s.length()), верните список, содержащий пустую строку.
2⃣ Вызовите функцию storeFirstOptions с строкой s, целым числом startPos и пустым списком firstOptions. Найдите набор символов, начиная с позиции startPos, и сохраните их в списке firstOptions. Это может быть один символ или все символы между скобками. Отсортируйте список firstOptions. Верните обновленное значение startPos, которое теперь указывает на первый индекс следующей группы символов в строке s, которую мы будем рассматривать. Сохраните это значение в переменной remStringStartPos. Сделайте рекурсивный вызов функции findAllWords(String, Integer) с строкой s и remStringStartPos. Сохраните возвращенный список слов в переменной wordsWithRemString.
3⃣ Переберите слова в wordsWithRemString и добавьте вышеуказанный символ в начало каждого слова, сохраняя новую строку в списке expandedWords. Верните список expandedWords.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан список оценок различных студентов, items, где items[i] = [IDi, scorei] представляет собой одну оценку студента с идентификатором IDi. Вычислите среднее значение пяти лучших оценок каждого студента.
Верните ответ в виде массива пар result, где result[j] = [IDj, topFiveAveragej] представляет студента с идентификатором IDj и его среднее значение пяти лучших оценок. Отсортируйте result по IDj в порядке возрастания.
Среднее значение пяти лучших оценок студента вычисляется путем сложения его пяти лучших оценок и деления на 5 с использованием целочисленного деления.
Пример:
Input: s = "{a,b}c{d,e}f"
Output: ["acdf","acef","bcdf","bcef"]class Solution:
def storeFirstOptions(self, s: str, startPos: int, firstOptions: List[str]) -> int:
if s[startPos] != '{':
firstOptions.append(s[startPos])
else:
startPos += 1
while s[startPos] != '}':
if s[startPos].islower():
firstOptions.append(s[startPos])
startPos += 1
firstOptions.sort()
return startPos + 1
def findAllWords(self, s: str, startPos: int) -> List[str]:
if startPos == len(s):
return [""]
firstOptions = []
remStringStartPos = self.storeFirstOptions(s, startPos, firstOptions)
wordsWithRemString = self.findAllWords(s, remStringStartPos)
expandedWords = []
for c in firstOptions:
for word in wordsWithRemString:
expandedWords.append(c + word)
return expandedWords
def expand(self, s: str) -> List[str]:
return self.findAllWords(s, 0)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Задача: 1058. Minimize Rounding Error to Meet Target
Сложность: medium
Учитывая массив цен [p1,p2...,pn] и цель, округлите каждую цену pi до Roundi(pi) так, чтобы округленный массив [Round1(p1),Round2(p2)...,Roundn(pn)] в сумме достиг заданной цели. Каждая операция Roundi(pi) может быть либо Floor(pi), либо Ceil(pi). Верните строку "-1", если округленный массив невозможно привести к целевому значению. В противном случае возвращается наименьшая ошибка округления, которая определяется как Σ |Roundi(pi) - (pi)| для i от 1 до n, в виде строки с тремя местами после десятичной дроби.
Пример:
👨💻 Алгоритм:
1⃣ Округли каждую цену вниз и вычисли текущую сумму округленных цен.
Найди разницу между целевой суммой и текущей суммой.
2⃣ Определи количество округлений вверх, необходимых для достижения целевой суммы.
Если разница отрицательная или больше количества элементов в массиве, верни "-1".
3⃣ Вычисли ошибки округления для всех элементов и отсортируй их по возрастанию.
Выбери необходимые округления вверх и вычисли общую ошибку округления.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Учитывая массив цен [p1,p2...,pn] и цель, округлите каждую цену pi до Roundi(pi) так, чтобы округленный массив [Round1(p1),Round2(p2)...,Roundn(pn)] в сумме достиг заданной цели. Каждая операция Roundi(pi) может быть либо Floor(pi), либо Ceil(pi). Верните строку "-1", если округленный массив невозможно привести к целевому значению. В противном случае возвращается наименьшая ошибка округления, которая определяется как Σ |Roundi(pi) - (pi)| для i от 1 до n, в виде строки с тремя местами после десятичной дроби.
Пример:
Input: prices = ["0.700","2.800","4.900"], target = 8
Output: "1.000"
Найди разницу между целевой суммой и текущей суммой.
Если разница отрицательная или больше количества элементов в массиве, верни "-1".
Выбери необходимые округления вверх и вычисли общую ошибку округления.
import math
def minimizeRoundingError(prices, target):
floors = [math.floor(float(p)) for p in prices]
ceils = [math.ceil(float(p)) for p in prices]
total_floor = sum(floors)
difference = target - total_floor
if difference < 0 or difference > len(prices):
return "-1"
rounding_errors = [(ceil - floor, float(p) - floor) for p, floor, ceil in zip(prices, floors, ceils)]
rounding_errors.sort(key=lambda x: x[1])
rounding_error_sum = sum(floor - float(p) for floor, p in zip(floors, prices))
for i in range(difference):
rounding_error_sum += 1
for i in range(difference):
rounding_error_sum += rounding_errors[i][1]
return "{:.3f}".format(rounding_error_sum)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Задача: 815. Bus Routes
Сложность: hard
Дан массив routes, представляющий автобусные маршруты, где routes[i] - это автобусный маршрут, который i-й автобус повторяет бесконечно.
Например, если routes[0] = [1, 5, 7], это означает, что 0-й автобус путешествует в последовательности 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ... бесконечно.
Вы начинаете на автобусной остановке source (вы изначально не находитесь в автобусе) и хотите добраться до автобусной остановки target. Перемещаться между автобусными остановками можно только на автобусах.
Верните наименьшее количество автобусов, которые вам нужно взять, чтобы доехать от source до target. Верните -1, если это невозможно.
Пример:
👨💻 Алгоритм:
1⃣ Верните 0, если source и target совпадают. Инициализируйте пустую карту adjList, чтобы хранить ребра, где ключ - это автобусная остановка, а значение - список целых чисел, обозначающих индексы маршрутов, которые имеют эту остановку. Инициализируйте пустую очередь q и неупорядоченное множество vis, чтобы отслеживать посещенные маршруты. Вставьте начальные маршруты в очередь q и отметьте их посещенными в vis.
2⃣ Итерация по очереди, пока она не пуста: извлеките маршрут из очереди, итерируйтесь по остановкам в маршруте. Если остановка равна target, верните busCount. В противном случае, итерируйтесь по маршрутам для этой остановки в карте adjList, добавьте непосещенные маршруты в очередь и отметьте их посещенными.
3⃣ Верните -1 после завершения обхода в ширину (BFS).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан массив routes, представляющий автобусные маршруты, где routes[i] - это автобусный маршрут, который i-й автобус повторяет бесконечно.
Например, если routes[0] = [1, 5, 7], это означает, что 0-й автобус путешествует в последовательности 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ... бесконечно.
Вы начинаете на автобусной остановке source (вы изначально не находитесь в автобусе) и хотите добраться до автобусной остановки target. Перемещаться между автобусными остановками можно только на автобусах.
Верните наименьшее количество автобусов, которые вам нужно взять, чтобы доехать от source до target. Верните -1, если это невозможно.
Пример:
Input: routes = [[1,2,7],[3,6,7]], source = 1, target = 6
Output: 2
Explanation: The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
class Solution:
def numBusesToDestination(self, routes, source, target):
if source == target:
return 0
from collections import defaultdict, deque
adjList = defaultdict(list)
for route, stops in enumerate(routes):
for stop in stops:
adjList[stop].append(route)
q = deque()
vis = set()
for route in adjList[source]:
q.append(route)
vis.add(route)
busCount = 1
while q:
for _ in range(len(q)):
route = q.popleft()
for stop in routes[route]:
if stop == target:
return busCount
for nextRoute in adjList[stop]:
if nextRoute not in vis:
vis.add(nextRoute)
q.append(nextRoute)
busCount += 1
return -1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🔥1
Задача: 1062. Longest Repeating Substring
Сложность: medium
Дана строка s. Вернуть длину самой длинной повторяющейся подстроки. Если повторяющаяся подстрока отсутствует, вернуть 0.
Пример:
👨💻 Алгоритм:
1⃣ Перемещайте скользящее окно длиной L по строке длиной N.
2⃣ Проверьте, находится ли строка в скользящем окне в хэш-наборе уже виденных строк. Если да, то повторяющаяся подстрока находится здесь. Если нет, сохраните строку из скользящего окна в хэш-наборе.
3⃣ Очевидный недостаток этого подхода — большое потребление памяти в случае длинных строк.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s. Вернуть длину самой длинной повторяющейся подстроки. Если повторяющаяся подстрока отсутствует, вернуть 0.
Пример:
Input: s = "abcd"
Output: 0
Explanation: There is no repeating substring.
class Solution:
def search(self, L, n, S):
seen = set()
for start in range(n - L + 1):
tmp = S[start:start + L]
if tmp in seen:
return start
seen.add(tmp)
return -1
def longestRepeatingSubstring(self, S):
n = len(S)
left, right = 1, n
while left <= right:
L = left + (right - left) // 2
if self.search(L, n, S) != -1:
left = L + 1
else:
right = L - 1
return left - 1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔2
Задача: 1250. Check If It Is a Good Array
Сложность: hard
Дан массив nums из целых положительных чисел. Ваша задача - выбрать некоторое подмножество nums, умножить каждый элемент на целое число и сложить все эти числа.Массив считается хорошим, если из него можно получить сумму, равную 1, при любом возможном подмножестве и множителе. Верните True, если массив хороший, иначе верните False.
Пример:
👨💻 Алгоритм:
1⃣ Если наибольший общий делитель (НОД) всех чисел в массиве равен 1, то массив считается хорошим.
2⃣ Если НОД всех чисел больше 1, то массив не считается хорошим
3⃣ Получить сумму, равную 1, умножая и складывая элементы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан массив nums из целых положительных чисел. Ваша задача - выбрать некоторое подмножество nums, умножить каждый элемент на целое число и сложить все эти числа.Массив считается хорошим, если из него можно получить сумму, равную 1, при любом возможном подмножестве и множителе. Верните True, если массив хороший, иначе верните False.
Пример:
Input: nums = [12,5,7,23]
Output: true
import math
from functools import reduce
def isGoodArray(nums):
return reduce(math.gcd, nums) == 1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Задача: 1431. Kids With the Greatest Number of Candies
Сложность: easy
Дано n детей с конфетами. Вам дан целочисленный массив candies, где каждый candies[i] представляет количество конфет у i-го ребенка, и целое число extraCandies, обозначающее количество дополнительных конфет, которые у вас есть.
Вернуть булев массив result длиной n, где result[i] равно true, если, дав i-му ребенку все дополнительные конфеты, он будет иметь наибольшее количество конфет среди всех детей, или false в противном случае.
Обратите внимание, что несколько детей могут иметь наибольшее количество конфет.
Пример:
👨💻 Алгоритм:
1⃣ Найдите максимальное количество конфет в массиве candies, сохраняя его в переменной maxCandies.
2⃣ Создайте булев список answer и пройдитесь по массиву candies, добавляя в answer значение true, если текущий ребенок с добавленными extraCandies имеет количество конфет больше или равное maxCandies, иначе добавляйте false.
3⃣ Верните список answer.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано n детей с конфетами. Вам дан целочисленный массив candies, где каждый candies[i] представляет количество конфет у i-го ребенка, и целое число extraCandies, обозначающее количество дополнительных конфет, которые у вас есть.
Вернуть булев массив result длиной n, где result[i] равно true, если, дав i-му ребенку все дополнительные конфеты, он будет иметь наибольшее количество конфет среди всех детей, или false в противном случае.
Обратите внимание, что несколько детей могут иметь наибольшее количество конфет.
Пример:
Input: candies = [2,3,5,1,3], extraCandies = 3
Output: [true,true,true,false,true]
Explanation: If you give all extraCandies to:
- Kid 1, they will have 2 + 3 = 5 candies, which is the greatest among the kids.
- Kid 2, they will have 3 + 3 = 6 candies, which is the greatest among the kids.
- Kid 3, they will have 5 + 3 = 8 candies, which is the greatest among the kids.
- Kid 4, they will have 1 + 3 = 4 candies, which is not the greatest among the kids.
- Kid 5, they will have 3 + 3 = 6 candies, which is the greatest among the kids.
class Solution:
def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]:
maxCandies = max(candies)
return [candy + extraCandies >= maxCandies for candy in candies]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤1
Задача: 1063. Number of Valid Subarrays
Сложность: hard
Дан целочисленный массив nums. Вернуть количество непустых подмассивов, в которых левый элемент не больше других элементов подмассива.
Подмассив — это непрерывная часть массива.
Пример:
👨💻 Алгоритм:
1⃣ нициализируйте переменную ans значением 0. Инициализируйте пустой стек st, который будет хранить индексы элементов в стеке.
2⃣ Итерируйте по элементам массива nums для каждого индекса i: продолжайте извлекать элементы из стека st, пока стек не станет пустым или элемент nums[i] не станет больше элемента на вершине стека. Для каждого извлеченного элемента добавляйте количество подмассивов как i - st.top(). Поместите текущий индекс i в стек.
3⃣ Извлеките все оставшиеся элементы из стека и для каждого рассмотрите размер nums как индекс следующего меньшего элемента. Соответственно, добавьте nums.size() - st.top() к переменной ans. Верните ans.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан целочисленный массив nums. Вернуть количество непустых подмассивов, в которых левый элемент не больше других элементов подмассива.
Подмассив — это непрерывная часть массива.
Пример:
Input: nums = [1,4,2,5,3]
Output: 11
Explanation: There are 11 valid subarrays: [1],[4],[2],[5],[3],[1,4],[2,5],[1,4,2],[2,5,3],[1,4,2,5],[1,4,2,5,3].
class Solution:
def validSubarrays(self, nums: List[int]) -> int:
ans = 0
st = []
for i in range(len(nums)):
while st and nums[i] < nums[st[-1]]:
ans += (i - st.pop())
st.append(i)
while st:
ans += (len(nums) - st.pop())
return ans
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1
Задача: 1162. As Far from Land as Possible
Сложность: medium
Дана сетка размером n x n, содержащая только значения 0 и 1, где 0 представляет воду, а 1 представляет землю. Найдите ячейку с водой, такое что её расстояние до ближайшей ячейки с землёй максимально, и верните это расстояние. Если в сетке нет ни земли, ни воды, верните -1.
Расстояние, используемое в этой задаче, - это манхэттенское расстояние: расстояние между двумя ячейками (x0, y0) и (x1, y1) равно |x0 - x1| + |y0 - y1|.
Пример:
👨💻 Алгоритм:
1⃣ Итерируйте по матрице и вставьте координаты ячеек с землёй в очередь. Инициализируйте переменную distance значением -1 для хранения текущего шага обхода в ширину (BFS). Также создайте копию матрицы visited для пометки ячеек с водой как посещённые, чтобы не вставлять их снова в очередь.
2⃣ Выполните BFS: Обходите текущие элементы в очереди и для каждого элемента проверяйте координаты в четырёх направлениях, являются ли они ячейками с водой (0). Если да, вставьте их в очередь и измените их на ячейки с землёй (1) в матрице visited. После каждого пройденного уровня (внутренний цикл while завершён), увеличьте переменную distance.
3⃣ Повторяйте, пока очередь не станет пустой. Верните значение distance. Если оно равно 0, это означает, что не было ячеек с водой и обход завершился после первого шага, поэтому верните -1. Если в матрице не было ячеек с землёй, цикл while вообще не начнётся, и переменная distance останется с начальным значением (-1).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана сетка размером n x n, содержащая только значения 0 и 1, где 0 представляет воду, а 1 представляет землю. Найдите ячейку с водой, такое что её расстояние до ближайшей ячейки с землёй максимально, и верните это расстояние. Если в сетке нет ни земли, ни воды, верните -1.
Расстояние, используемое в этой задаче, - это манхэттенское расстояние: расстояние между двумя ячейками (x0, y0) и (x1, y1) равно |x0 - x1| + |y0 - y1|.
Пример:
Input: grid = [[1,0,1],[0,0,0],[1,0,1]]
Output: 2
Explanation: The cell (1, 1) is as far as possible from all the land with distance 2.
from collections import deque
class Solution:
def maxDistance(self, grid: List[List[int]]) -> int:
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
visited = [row[:] for row in grid]
q = deque()
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1:
q.append((i, j))
distance = -1
while q:
qSize = len(q)
for _ in range(qSize):
landCell = q.popleft()
for dir in directions:
x, y = landCell[0] + dir[0], landCell[1] + dir[1]
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and visited[x][y] == 0:
visited[x][y] = 1
q.append((x, y))
distance += 1
return -1 if distance == 0 else distance
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🔥1