Python | LeetCode
10.1K subscribers
150 photos
1.04K links
Cайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp

Тесты t.me/+20tRfhrwPpM4NDQy
Вопросы собесов t.me/+cnJC0_ZeZ_I0OGY6
Вакансии t.me/+cXGKkrOY2-w3ZTky
Download Telegram
#medium
Задача: 738. Monotone Increasing Digits

Целое число имеет монотонно возрастающие цифры тогда и только тогда, когда каждая пара соседних цифр x и y удовлетворяет x <= y. Задав целое число n, верните наибольшее число, которое меньше или равно n с монотонно возрастающими цифрами.

Пример:
Input: n = 10
Output: 9


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

1⃣Преобразуйте число в строку для удобства обработки.

2⃣Найдите позицию, где последовательность перестает быть монотонной.

3⃣Уменьшите соответствующую цифру и установите все последующие цифры в 9.

😎 Решение:
def monotoneIncreasingDigits(n):
digits = list(str(n))
mark = len(digits)

for i in range(len(digits) - 1, 0, -1):
if digits[i] < digits[i - 1]:
mark = i
digits[i - 1] = str(int(digits[i - 1]) - 1)

for i in range(mark, len(digits)):
digits[i] = '9'

return int("".join(digits))


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
#medium
Задача: 739. Daily Temperatures

Задав массив целых чисел temperature, представляющих дневные температуры, верните массив answer, такой, что answer[i] - это количество дней, которые нужно подождать после i-го дня, чтобы температура стала теплее. Если в будущем не существует дня, для которого это возможно, сохраните answer[i] == 0.

Пример:
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]


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

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

2⃣Пройдите по массиву температур и для каждого дня: Пока текущая температура больше температуры дня на вершине стека, обновляйте массив ответов и удаляйте вершину стека. Добавьте текущий день в стек.

3⃣Возвращайте массив ответов.

😎 Решение:
def dailyTemperatures(T):
n = len(T)
answer = [0] * n
stack = []

for i in range(n):
while stack and T[i] > T[stack[-1]]:
j = stack.pop()
answer[j] = i - j
stack.append(i)

return answer


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
#medium
Задача: 740. Delete and Earn

Вам дан целочисленный массив nums. Вы хотите максимизировать количество очков, выполнив следующую операцию любое количество раз: Выберите любой элемент nums[i] и удалите его, чтобы заработать nums[i] очков. После этого вы должны удалить каждый элемент, равный nums[i] - 1, и каждый элемент, равный nums[i] + 1. Верните максимальное количество очков, которое вы можете заработать, применив вышеуказанную операцию некоторое количество раз.

Пример:
Input: nums = [3,4,2]
Output: 6


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

1⃣Подсчитайте количество каждого числа в массиве nums.

2⃣Используйте динамическое программирование для расчета максимальных очков, которые можно заработать, используя накопленный результат для чисел, меньших текущего. Добавьте текущий день в стек.

3⃣Для каждого числа num в nums, учитывайте два случая: не брать число или взять число и добавить его очки.

😎 Решение:
def deleteAndEarn(nums):
from collections import Counter

count = Counter(nums)
prev = None
avoid = using = 0

for num in sorted(count):
if num - 1 != prev:
new_avoid, new_using = max(avoid, using), num * count[num] + max(avoid, using)
else:
new_avoid, new_using = max(avoid, using), num * count[num] + avoid
avoid, using = new_avoid, new_using
prev = num

return max(avoid, using)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#hard
Задача: 741. Cherry Pickup

Вам дана сетка n x n, представляющая поле вишен. Каждая клетка - одно из трех возможных целых чисел. 0 означает, что клетка пуста, и вы можете пройти через нее, 1 означает, что клетка содержит вишню, которую вы можете сорвать и пройти через нее, или -1 означает, что клетка содержит шип, который преграждает вам путь. Верните максимальное количество вишен, которое вы можете собрать, следуя следующим правилам: Начиная с позиции (0, 0) и достигая (n - 1, n - 1) путем перемещения вправо или вниз через допустимые клетки пути (клетки со значением 0 или 1).
После достижения (n - 1, n - 1) вернитесь в (0, 0), двигаясь влево или вверх по клеткам с действительными путями. Проходя через клетку пути, содержащую вишню, вы поднимаете ее, и клетка становится пустой клеткой 0. Если между (0, 0) и (n - 1, n - 1) нет действительного пути, то вишни собрать нельзя.

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


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

1⃣Используйте динамическое программирование для подсчета максимального количества вишен, которые можно собрать при движении от (0, 0) до (n - 1, n - 1).

2⃣Примените еще один проход с использованием динамического программирования для движения обратно от (n - 1, n - 1) до (0, 0), чтобы учитывать вишни, собранные на обратном пути.

3⃣Объедините результаты двух проходов, чтобы найти максимальное количество вишен, которые можно собрать.

😎 Решение:
def cherryPickup(grid):
n = len(grid)
dp = [[[-float('inf')] * n for _ in range(n)] for _ in range(n)]
dp[0][0][0] = grid[0][0]

for k in range(1, 2 * (n - 1) + 1):
for i1 in range(max(0, k - n + 1), min(n, k + 1)):
for i2 in range(max(0, k - n + 1), min(n, k + 1)):
j1, j2 = k - i1, k - i2
if 0 <= j1 < n and 0 <= j2 < n and grid[i1][j1] != -1 and grid[i2][j2] != -1:
max_cherries = max(
dp[i1 - 1][i2 - 1][k - 1] if i1 > 0 and i2 > 0 else -float('inf'),
dp[i1 - 1][i2][k - 1] if i1 > 0 else -float('inf'),
dp[i1][i2 - 1][k - 1] if i2 > 0 else -float('inf'),
dp[i1][i2][k - 1]
)
if max_cherries != -float('inf'):
dp[i1][i2][k] = max_cherries + grid[i1][j1]
if i1 != i2:
dp[i1][i2][k] += grid[i2][j2]

return max(0, dp[n - 1][n - 1][2 * (n - 1)])


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 742. Closest Leaf in a Binary Tree

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

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


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

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

2⃣Найдите все листья и минимальное расстояние до них, используя BFS, начиная с найденного узла k.

3⃣Верните значение ближайшего листа.

😎 Решение:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right

def findClosestLeaf(root, k):
from collections import deque, defaultdict

def find_path(node, k, path):
if not node:
return False
path.append(node)
if node.val == k:
return True
if (node.left and find_path(node.left, k, path)) or (node.right and find_path(node.right, k, path)):
return True
path.pop()
return False

def find_leaves(node, leaves):
if not node:
return
if not node.left and not node.right:
leaves[node] = 0
find_leaves(node.left, leaves)
find_leaves(node.right, leaves)

path = []
find_path(root, k, path)

leaves = {}
find_leaves(root, leaves)

queue = deque([(path[-1], 0)])
visited = set()

while queue:
node, dist = queue.popleft()
if node in leaves:
return node.val
visited.add(node)
if node.left and node.left not in visited:
queue.append((node.left, dist + 1))
if node.right and node.right not in visited:
queue.append((node.right, dist + 1))
if len(path) > 1 and path[-2] not in visited:
queue.append((path.pop(), dist + 1))
return -1


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#medium
Задача: 743. Network Delay Time

Дана сеть из узлов, помеченных от 1 до n. Также дано times - список времен прохождения сигнала в виде направленных ребер times[i] = (ui, vi, wi), где ui - исходный узел, vi - целевой узел, а wi - время прохождения сигнала от источника до цели. Мы пошлем сигнал из заданного узла k. Верните минимальное время, которое потребуется всем узлам, чтобы получить сигнал. Если все узлы не могут получить сигнал, верните -1.

Пример:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
Output: 2


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

1⃣Представьте граф в виде списка смежности.

2⃣Используйте алгоритм Дейкстры для нахождения кратчайших путей от узла k до всех других узлов.

3⃣Найдите максимальное значение среди кратчайших путей к узлам. Если какой-либо узел недостижим, верните -1.

😎 Решение:
import heapq

def networkDelayTime(times, n, k):
graph = {i: [] for i in range(1, n + 1)}
for u, v, w in times:
graph[u].append((v, w))

min_heap = [(0, k)]
min_time = {i: float('inf') for i in range(1, n + 1)}
min_time[k] = 0

while min_heap:
time, node = heapq.heappop(min_heap)
for neighbor, t in graph[node]:
new_time = time + t
if new_time < min_time[neighbor]:
min_time[neighbor] = new_time
heapq.heappush(min_heap, (new_time, neighbor))

max_time = max(min_time.values())
return max_time if max_time < float('inf') else -1


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥1
#easy
Задача: 744. Find Smallest Letter Greater Than Target

Нам дан массив символов letters, отсортированный в неубывающем порядке, и символ target. В массиве letters есть как минимум два разных символа. Возвращается наименьший символ в letters, который лексикографически больше target. Если такого символа не существует, возвращается первый символ в буквах.

Пример:
Input: letters = ["c","f","j"], target = "a"
Output: "c"


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

1⃣Использовать бинарный поиск для нахождения позиции первого символа в letters, который лексикографически больше target.

2⃣Если найденный символ существует, вернуть его.

3⃣Если такого символа не существует, вернуть первый символ в letters.

😎 Решение:
def nextGreatestLetter(letters, target):
left, right = 0, len(letters) - 1
while left <= right:
mid = (left + right) // 2
if letters[mid] > target:
right = mid - 1
else:
left = mid + 1
return letters[left % len(letters)]


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥1
#hard
Задача: 745. Prefix and Suffix Search

Создайте специальный словарь, в котором поиск слов осуществляется по префиксу и суффиксу. Реализуйте класс WordFilter: WordFilter(string[] words) Инициализирует объект со словами в словаре. f(string pref, string suff) Возвращает индекс слова в словаре, которое имеет префикс pref и суффикс suff. Если существует более одного допустимого индекса, возвращается наибольший из них. Если в словаре нет такого слова, возвращается -1.

Пример:
Input: letters = ["c","f","j"], target = "a"
Output: "c"


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

1⃣Сохраните слова и их индексы в словаре.

2⃣Создайте объединенные ключи, состоящие из префиксов и суффиксов для всех возможных комбинаций.

3⃣Реализуйте функцию поиска, которая ищет наибольший индекс слова по префиксу и суффиксу.

😎 Решение:
class WordFilter:
def __init__(self, words):
self.prefix_suffix_map = {}
for index, word in enumerate(words):
length = len(word)
for prefix_length in range(1, length + 1):
for suffix_length in range(1, length + 1):
key = word[:prefix_length] + '#' + word[-suffix_length:]
self.prefix_suffix_map[key] = index

def f(self, pref, suff):
key = pref + '#' + suff
return self.prefix_suffix_map.get(key, -1)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥1
#easy
Задача: 746. Min Cost Climbing Stairs

Вам дан целочисленный массив cost, где cost[i] - стоимость i-й ступеньки на лестнице. После оплаты стоимости вы можете подняться на одну или две ступеньки. Вы можете начать со ступеньки с индексом 0 или со ступеньки с индексом 1. Верните минимальную стоимость достижения вершины этажа.

Пример:
Input: cost = [10,15,20]
Output: 15


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

1⃣Создать массив dp, где dp[i] хранит минимальную стоимость достижения i-й ступеньки.

2⃣Инициализировать dp[0] и dp[1] как cost[0] и cost[1] соответственно. Заполнить dp используя минимальную стоимость подъема с предыдущих ступенек.

3⃣Вернуть минимальную стоимость достижения вершины.

😎 Решение:
def minCostClimbingStairs(cost):
n = len(cost)
dp = [0] * n
dp[0] = cost[0]
dp[1] = cost[1]
for i in range(2, n):
dp[i] = cost[i] + min(dp[i - 1], dp[i - 2])
return min(dp[-1], dp[-2])


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥1
#easy
Задача: 747. Largest Number At Least Twice of Others

Вам дан целочисленный массив nums, в котором наибольшее целое число уникально. Определите, является ли наибольший элемент массива по крайней мере в два раза больше всех остальных чисел в массиве. Если да, то верните индекс самого большого элемента, в противном случае верните -1.

Пример:
Input: nums = [3,6,1,0]
Output: 1


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

1⃣Найдите максимальный элемент в массиве и его индекс.

2⃣Проверьте, является ли этот максимальный элемент по крайней мере в два раза больше всех остальных элементов массива.

3⃣Если условие выполняется, верните индекс максимального элемента, иначе верните -1.

😎 Решение:
def dominantIndex(nums):
max_val = max(nums)
max_index = nums.index(max_val)
for num in nums:
if num != max_val and max_val < 2 * num:
return -1
return max_index


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🔥1
#easy
Задача: 748. Shortest Completing Word

Вам дан целочисленный массив nums, в котором наибольшее целое число уникально. Определите, является ли наибольший элемент массива по крайней мере в два раза больше всех остальных чисел в массиве. Если да, то верните индекс самого большого элемента, в противном случае верните -1.

Пример:
Input: licensePlate = "1s3 PSt", words = ["step","steps","stripe","stepple"]
Output: "steps"


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

1⃣Извлечь все буквы из licensePlate, игнорируя цифры и пробелы, и создать словарь для подсчета частоты каждой буквы.

2⃣Пройти по массиву words, проверяя каждое слово на соответствие требованиям.

3⃣Найти самое короткое завершающее слово среди подходящих.

😎 Решение:
import collections

def shortestCompletingWord(licensePlate, words):
def get_char_count(s):
count = collections.Counter()
for char in s:
if char.isalpha():
count[char.lower()] += 1
return count

license_count = get_char_count(licensePlate)

def is_completing_word(word, license_count):
word_count = collections.Counter(word)
for char, cnt in license_count.items():
if word_count[char] < cnt:
return False
return True

result = None
for word in words:
if is_completing_word(word, license_count):
if result is None or len(word) < len(result):
result = word
return result


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔21
#hard
Задача: 749. Contain Virus

Вирус быстро распространяется, и ваша задача - поместить зараженную область в карантин, установив стены. Мир моделируется как бинарная сетка m x n isInfected, где isInfected[i][j] == 0 обозначает незараженные клетки, а isInfected[i][j] == 1 - клетки, зараженные вирусом. Между любыми двумя соседними клетками, расположенными в четырех направлениях, может быть установлена стена (и только одна стена) на общей границе. Каждую ночь вирус распространяется на все соседние клетки во всех четырех направлениях, если не блокируется стеной. Ресурсы ограничены. Каждый день вы можете устанавливать стены только вокруг одного региона (то есть пораженной области (непрерывного блока зараженных клеток), которая угрожает наибольшим количеством незараженных клеток на следующую ночь). Ничьей не будет никогда. Верните количество стен, использованных для карантина всех зараженных регионов. Если мир будет полностью заражен, верните количество использованных стен.

Пример:
Input: isInfected = [[0,1,0,0,0,0,0,1],[0,1,0,0,0,0,0,1],[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0]]
Output: 10


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

1⃣Определите все зараженные регионы и для каждого региона определите количество угрожаемых незараженных клеток.

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

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

😎 Решение:
def containVirus(isInfected):
def neighbors(r, c):
for nr, nc in [(r-1, c), (r+1, c), (r, c-1), (r, c+1)]:
if 0 <= nr < len(isInfected) and 0 <= nc < len(isInfected[0]):
yield nr, nc

def dfs(r, c, region, frontiers, walls):
stack = [(r, c)]
region.add((r, c))
while stack:
r, c = stack.pop()
for nr, nc in neighbors(r, c):
if isInfected[nr][nc] == 1 and (nr, nc) not in region:
stack.append((nr, nc))
region.add((nr, nc))
elif isInfected[nr][nc] == 0:
frontiers.add((nr, nc))
walls.add((r, c, nr, nc))

total_walls = 0
while True:
regions = []
frontiers = []
walls = []
visited = set()

for r in range(len(isInfected)):
for c in range(len(isInfected[0])):
if isInfected[r][c] == 1 and (r, c) not in visited:
region = set()
frontier = set()
wall = set()
dfs(r, c, region, frontier, wall)
visited |= region
if frontier:
regions.append(region)
frontiers.append(frontier)
walls.append(wall)

if not regions:
break

max_threat_index = max(range(len(frontiers)), key=lambda i: len(frontiers[i]))
total_walls += len(walls[max_threat_index])

for i, region in enumerate(regions):
if i == max_threat_index:
for r, c in region:
isInfected[r][c] = -1
else:
for r, c in frontiers[i]:
isInfected[r][c] = 1

return total_walls


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#medium
Задача: 750. Number Of Corner Rectangles

Дан указатель на начало односвязного списка и два целых числа left и right, где left <= right. Необходимо перевернуть узлы списка, начиная с позиции left и заканчивая позицией right, и вернуть измененный список.

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


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

1⃣Пройдите по строкам матрицы. Для каждой пары строк, найдите все столбцы, где оба значения равны 1.

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

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

😎 Решение:
def countCornerRectangles(grid):
count = 0
for i in range(len(grid)):
for j in range(i + 1, len(grid)):
num_pairs = 0
for k in range(len(grid[0])):
if grid[i][k] == 1 and grid[j][k] == 1:
num_pairs += 1
if num_pairs > 1:
count += num_pairs * (num_pairs - 1) // 2
return count


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2
#medium
Задача: 751. IP to CIDR

Дан указатель на начало односвязного списка и два целых числа left и right, где left <= right. Необходимо перевернуть узлы списка, начиная с позиции left и заканчивая позицией right, и вернуть измененный список.

Пример:
Input: ip = "255.0.0.7", n = 10
Output: ["255.0.0.7/32","255.0.0.8/29","255.0.0.16/32"]


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

1⃣Преобразовать начальный IP-адрес в целое число.

2⃣Пока количество оставшихся IP-адресов n больше нуля: Определить наибольший блок, который начинается с текущего IP-адреса и не превышает количество оставшихся IP-адресов. Добавить этот блок к результату. Увеличить текущий IP-адрес на размер блока. Уменьшить количество оставшихся IP-адресов n.

3⃣Преобразовать блоки обратно в формат CIDR и вернуть их.

😎 Решение:
def ip_to_int(ip):
parts = ip.split('.')
return (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])

def int_to_ip(num):
return f"{(num >> 24) & 255}.{(num >> 16) & 255}.{(num >> 8) & 255}.{num & 255}"

def cidr(ip, prefix_length):
return f"{ip}/{prefix_length}"

def find_cidr_blocks(start_ip, n):
start = ip_to_int(start_ip)
result = []

while n > 0:
max_size = 1
while max_size <= start and max_size <= n:
max_size <<= 1
max_size >>= 1

while start % max_size != 0:
max_size >>= 1

result.append(cidr(int_to_ip(start), 32 - max_size.bit_length() + 1))
start += max_size
n -= max_size

return result


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1💊1
#medium
Задача: 752. Open the Lock

Перед вами замок с 4 круглыми колесами. Каждое колесо имеет 10 слотов: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'. Колеса могут свободно вращаться и оборачиваться: например, мы можем повернуть "9" так, чтобы получился "0", или "0" так, чтобы получился "9". Каждый ход состоит из поворота одного колеса на один слот. Изначально замок начинается с '0000', строки, представляющей состояние 4 колес. Вам дан список тупиков, то есть если замок отобразит любой из этих кодов, колеса замка перестанут вращаться, и вы не сможете его открыть. Учитывая цель, представляющую значение колес, которое позволит отпереть замок, верните минимальное общее количество оборотов, необходимое для открытия замка, или -1, если это невозможно.

Пример:
Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
Output: 6


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

1⃣Используйте алгоритм BFS для поиска кратчайшего пути от начального состояния '0000' до целевого состояния, избегая тупиков. Инициализируйте очередь с начальным состоянием '0000' и начальным шагом 0. Используйте множество для отслеживания посещенных состояний, чтобы избежать повторного посещения одного и того же состояния.

2⃣Для каждого состояния в очереди: Проверьте все возможные переходы на следующий шаг, вращая каждое колесо на +1 и -1. Если найденное состояние является целевым, верните количество шагов. Если найденное состояние не является тупиком и не было посещено ранее, добавьте его в очередь и отметьте как посещенное.

3⃣Если очередь пуста и целевое состояние не найдено, верните -1.

😎 Решение:
from collections import deque

def openLock(deadends, target):
def neighbors(node):
for i in range(4):
x = int(node[i])
for d in (-1, 1):
y = (x + d) % 10
yield node[:i] + str(y) + node[i+1:]

dead = set(deadends)
queue = deque([('0000', 0)])
visited = {'0000'}

while queue:
node, steps = queue.popleft()
if node == target:
return steps
if node in dead:
continue
for neighbor in neighbors(node):
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, steps + 1))

return -1


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#medium
Задача: 753. Cracking the Safe

Имеется сейф, защищенный паролем. Пароль представляет собой последовательность из n цифр, каждая из которых может находиться в диапазоне [0, k - 1]. Сейф имеет особый способ проверки пароля. Например, правильный пароль - "345", а вы вводите "012345": после ввода 0 последние 3 цифры - "0", что неверно. После ввода 1 последние 3 цифры - "01", что неверно. После ввода 2 последние 3 цифры - "012", что неверно.
После ввода 3 последние 3 цифры - "123", что неверно. После ввода 4 последние 3 цифры - "234", что неверно. После ввода 5 последние 3 цифры - "345", что верно, и сейф разблокируется. Верните любую строку минимальной длины, которая разблокирует сейф на определенном этапе ввода.

Пример:
Input: n = 1, k = 2
Output: "10"


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

1⃣Создайте граф, где каждая вершина представляет собой строку длины n-1, а каждое ребро между двумя вершинами представляет собой добавление одной из цифр из диапазона [0, k-1].

2⃣Используйте алгоритм Эйлерова пути или цикла для нахождения пути, который проходит через каждое ребро ровно один раз.

3⃣Составьте итоговую строку, которая включает начальную вершину и все добавленные цифры.

😎 Решение:
def crackSafe(n, k):
seen = set()
result = []

def dfs(node):
for x in range(k):
neighbor = node + str(x)
if neighbor not in seen:
seen.add(neighbor)
dfs(neighbor[1:])
result.append(str(x))

start_node = '0' * (n - 1)
dfs(start_node)
return start_node + ''.join(result)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Forwarded from easyoffer
На easyoffer 2.0 появится:
🎯 Тренажер "Проработка вопросов"

Метод интервальных повторений и флеш-карточки
Персональный подход изучения на основе ваших ответов
Упор на самые частые вопросы

📌 Интервальные повторения по карточкам это научно доказанный метод эффективного обучения. Каждая карточка – это вопрос, который задают на собеседовании, вы можете выбрать "Не знаю", "Знаю", "Не спрашивать". После ответа вам показывается правильный ответ и возможность изучить вопрос подробнее (примеры ответов других людей). От ваших ответов зависит то, как часто карточки будут показываться на следующей тренировке. Трудные вопросы показываются чаще, простые – реже. Это позволяет бить в слабые места. Кроме того, изначальный порядок карточек зависит от частотности (вероятности встретить вопрос).

🚀 Благодаря этому тренажеру вы сможете очень быстро подготовиться к собеседованию, т.к. фокусируетесь отвечать на самые частые вопросы. Именно так готовился я сам, когда искал первую работу программистом.

Уже в течение недели я объявлю о старте краудфандинговой кампании на сбор финансирования, чтобы ускорить разработку сайта. Все кто поддержит проект до официального релиза получат самые выгодные условия пользования сервисом. А именно 1 год доступа к сайту по цене месячной подписки.

‼️ Очень важно, чтобы как можно больше людей поддержали проект в первые дни, по-этому те кто окажет поддержку первыми получат еще более выгодную стоимость на годовую подписку и существенный 💎 бонус о котором я позже расскажу в этом телеграм канале. Подписывайтесь, чтобы узнать о старте проекта раньше других и воспользоваться лимитированными вознаграждениями.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#medium
Задача: 754. Reach a Number

Вы стоите в позиции 0 на бесконечной числовой прямой. В позиции target находится пункт назначения. Вы можете сделать некоторое количество ходов numMoves так, чтобы: на каждом ходу вы могли пойти либо налево, либо направо. Во время i-го хода (начиная с i == 1 до i == numMoves) вы делаете i шагов в выбранном направлении. Учитывая целое число target, верните минимальное количество ходов (т.е. минимальное numMoves), необходимое для достижения пункта назначения.

Пример:
Input: target = 2
Output: 3


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

1⃣Инициализируйте переменную для текущей позиции (position) и счетчик шагов (steps).

2⃣Используйте цикл, чтобы добавлять к position текущее количество шагов и увеличивать steps.

3⃣Если position достигает или превышает target и разница между position и target четная, остановите цикл и верните steps.

😎 Решение:
def reachTarget(target):
target = abs(target)
position = 0
steps = 0
while position < target or (position - target) % 2 != 0:
steps += 1
position += steps
return steps


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#medium
Задача: 755. Pour Water

Вы стоите в позиции 0 на бесконечной числовой прямой. В позиции target находится пункт назначения. Вы можете сделать некоторое количество ходов numMoves так, чтобы: на каждом ходу вы могли пойти либо налево, либо направо. Во время i-го хода (начиная с i == 1 до i == numMoves) вы делаете i шагов в выбранном направлении. Учитывая целое число target, верните минимальное количество ходов (т.е. минимальное numMoves), необходимое для достижения пункта назначения.

Пример:
Input: heights = [2,1,1,2,1,2,2], volume = 4, k = 3
Output: [2,2,2,3,2,2,2]


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

1⃣Инициализируйте цикл для добавления объема воды.

2⃣Для каждой единицы воды: Проверьте, может ли вода двигаться влево и упасть на более низкий уровень. Если нет, проверьте, может ли вода двигаться вправо и упасть на более низкий уровень. Если нет, добавьте воду в текущую позицию.

3⃣Повторите шаг 2, пока не будет добавлен весь объем воды.

😎 Решение:
def pourWater(heights, volume, k):
for _ in range(volume):
drop_index = k
for d in (-1, 1):
i = k
while 0 <= i + d < len(heights) and heights[i + d] <= heights[i]:
if heights[i + d] < heights[i]:
drop_index = i + d
i += d
if drop_index != k:
break
heights[drop_index] += 1
return heights


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥1🤔1
#medium
Задача: 756. Pyramid Transition Matrix

Вы складываете блоки так, чтобы получилась пирамида. Каждый блок имеет цвет, который представлен одной буквой. Каждый ряд блоков содержит на один блок меньше, чем ряд под ним, и располагается по центру сверху. Чтобы пирамида выглядела эстетично, допускаются только определенные треугольные узоры. Треугольный узор состоит из одного блока, уложенного поверх двух блоков. Шаблоны задаются в виде списка допустимых трехбуквенных строк, где первые два символа шаблона представляют левый и правый нижние блоки соответственно, а третий символ - верхний блок. Например, "ABC" представляет треугольный шаблон с блоком 'C', уложенным поверх блоков 'A' (слева) и 'B' (справа). Обратите внимание, что это отличается от "BAC", где "B" находится слева внизу, а "A" - справа внизу. Вы начинаете с нижнего ряда блоков bottom, заданного в виде одной строки, который вы должны использовать в качестве основания пирамиды. Учитывая bottom и allowed, верните true, если вы можете построить пирамиду до самой вершины так, чтобы каждый треугольный узор в пирамиде был в allowed, или false в противном случае.

Пример:
Input: bottom = "BCD", allowed = ["BCC","CDE","CEA","FFF"]
Output: true


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

1⃣Создайте структуру данных для хранения допустимых треугольных узоров.

2⃣Напишите рекурсивную функцию, которая проверяет возможность построения следующего уровня пирамиды.

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

😎 Решение:
def pyramidTransition(bottom, allowed):
from collections import defaultdict

allowed_dict = defaultdict(list)
for pattern in allowed:
allowed_dict[pattern[:2]].append(pattern[2])

def can_build(current_level):
if len(current_level) == 1:
return True
next_level = []
for i in range(len(current_level) - 1):
if current_level[i:i+2] not in allowed_dict:
return False
next_level.append(allowed_dict[current_level[i:i+2]])
return any(can_build("".join(c)) for c in product(*next_level))

return can_build(bottom)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#hard
Задача: 757. Set Intersection Size At Least Two

Вам дан двумерный целочисленный массив intervals, в котором intervals[i] = [starti, endi] представляет все целые числа от starti до endi включительно. Содержащее множество - это массив nums, в котором каждый интервал из intervals содержит не менее двух целых чисел в nums. Например, если intervals = [[1,3], [3,7], [8,9]], то [1,2,4,7,8,9] и [2,3,4,8,9] - содержащие множества. Верните минимально возможный размер содержащего множества.

Пример:
Input: intervals = [[1,3],[3,7],[8,9]]
Output: 5


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

1⃣Отсортируйте интервалы по их конечным точкам.

2⃣Инициализируйте пустое множество для хранения чисел.

3⃣Пройдите по каждому интервалу, добавляя необходимые числа в множество так, чтобы каждый интервал содержал не менее двух чисел из этого множества.

😎 Решение:
def minSetSize(intervals):
intervals.sort(key=lambda x: x[1])
nums = []
for start, end in intervals:
if not nums or nums[-1] < start:
nums.append(end - 1)
nums.append(end)
elif nums[-1] == end - 1:
nums.append(end)
return len(nums)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
3