Python | LeetCode
الذهاب إلى القناة على Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
إظهار المزيد8 924
المشتركون
-1024 ساعات
-427 أيام
-12730 أيام
أرشيف المشاركات
8 922
#medium
Задача: 510. Inorder Successor in BST II
Дан узел в двоичном дереве поиска, верните его последующего (in-order successor) в этом дереве. Если у узла нет последующего, верните null.
Последующий узла — это узел с наименьшим ключом, большим, чем node.val.
Вы будете иметь прямой доступ к узлу, но не к корню дерева. Каждый узел будет иметь ссылку на своего родителя. Ниже приведено определение для Node:
class Node {
public int val;
public Node left;
public Node right;
public Node parent;
}
Пример:
Input: tree = [5,3,6,2,4,null,null,1], node = 6 Output: null Explanation: There is no in-order successor of the current node, so the answer is null.👨💻 Алгоритм: 1⃣Проверка правого поддерева Если у узла есть правый потомок, перейдите к правому узлу, затем спускайтесь влево до самого нижнего узла. Этот узел будет следующим узлом в порядке in-order. 2⃣Поиск предка Если у узла нет правого потомка, поднимайтесь по дереву до тех пор, пока узел не станет левым потомком своего родителя. Родитель этого узла будет следующим узлом в порядке in-order. 3⃣Возвращение результата Верните найденный узел или null, если следующий узел не найден. 😎 Решение:
class Node:
def __init__(self, val=0, left=None, right=None, parent=None):
self.val = val
self.left = left
self.right = right
self.parent = parent
class Solution:
def inorderSuccessor(self, x: 'Node') -> 'Node':
if x.right:
x = x.right
while x.left:
x = x.left
return x
while x.parent and x == x.parent.right:
x = x.parent
return x.parent
Ставь 👍 и забирай 📚 Базу знаний8 922
#easy
Задача: 724. Find Pivot Index
Если задан массив целых чисел nums, вычислите поворотный индекс этого массива. Поворотный индекс - это индекс, при котором сумма всех чисел строго слева от индекса равна сумме всех чисел строго справа от индекса. Если индекс находится на левом краю массива, то сумма слева равна 0, так как слева нет элементов. Это относится и к правому краю массива. Возвращается самый левый поворотный индекс. Если такого индекса не существует, возвращается -1.
Пример:
Input: nums = [1,7,3,6,5,6] Output: 3👨💻 Алгоритм: 1⃣Вычислите сумму всех элементов массива. 2⃣Пройдите по массиву, вычисляя текущую сумму элементов слева и проверяя, равна ли она разности между общей суммой и текущей суммой справа. 3⃣Если текущий индекс удовлетворяет условию, верните его; если нет, продолжайте проверку. Если такой индекс не найден, верните -1. 😎 Решение:
def pivotIndex(nums):
total_sum = sum(nums)
left_sum = 0
for i, num in enumerate(nums):
if left_sum == (total_sum - left_sum - num):
return i
left_sum += num
return -1
Ставь 👍 и забирай 📚 Базу знаний8 922
Вебинар про UserGate SIEM
⚡ Отечественные компании каждый день сталкиваются с различными рисками и угрозами, часть из которых помогает закрыть отказоустойчивость.
📊Спикеры:
- Дмитрий Чеботарев, менеджер по развитию UserGate SIEM;
- Дмитрий Богданов, ведущий инженер UserGate.
✅ Расскажут об отказоустойчивости и кластеризации и о том, для чего они нужны;
✅ Покажут кейсы использования.
Зарегистрироваться
#реклама 16+
webinar.usergate.com
О рекламодателе
8 922
#medium
Задача: 340. Longest Substring with At Most K Distinct Characters
Дана строка s и целое число k. Верните длину самой длинной подстроки s, которая содержит не более k различных символов.
Пример:
Input: n = 27 Output: true Explanation: 27 = 3^3👨💻 Алгоритм: 1⃣Инициализация Используйте два указателя (left и right) для отслеживания текущего окна в строке. Создайте словарь для отслеживания количества каждого символа в текущем окне. Инициализируйте переменные для хранения максимальной длины подстроки (max_length). 2⃣Раздвижение окна Перемещайте правый указатель (right) по строке и обновляйте словарь. Если количество различных символов в словаре превышает k, перемещайте левый указатель (left) вправо, уменьшая счетчик символов, пока количество различных символов снова не станет меньше или равно k. 3⃣Обновление максимальной длины На каждом шаге проверяйте и обновляйте максимальную длину подстроки, если текущее окно содержит не более k различных символов. В конце верните максимальную длину подстроки. 😎 Решение:
class Solution:
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
left = 0
right = 0
char_count = {}
max_length = 0
while right < len(s):
char_count[s[right]] = char_count.get(s[right], 0) + 1
while len(char_count) > k:
char_count[s[left]] -= 1
if char_count[s[left]] == 0:
del char_count[s[left]]
left += 1
max_length = max(max_length, right - left + 1)
right += 1
return max_length
Ставь 👍 и забирай 📚 Базу знаний8 922
#easy
Задача: 509. Fibonacci Number
Числа Фибоначчи, обычно обозначаемые как F(n), образуют последовательность, называемую последовательностью Фибоначчи, так что каждое число является суммой двух предыдущих, начиная с 0 и 1. То есть,
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), для n > 1.
Дано n, вычислите F(n).
Пример:
Input: n = 3 Output: 2 Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.👨💻 Алгоритм: 1⃣Проверка начального условия Если N <= 1, вернуть N. 2⃣Инициализация переменных Инициализируйте current значением 0. Инициализируйте prev1 значением 1, что будет представлять fib(N-1) при вычислении текущего значения. Инициализируйте prev2 значением 0, что будет представлять fib(N-2) при вычислении текущего значения. 3⃣Итерация и вычисление Итерация от 2 до N включительно. На каждой итерации: установите current как сумму prev1 и prev2. Обновите prev2 значением prev1. Обновите prev1 значением current. Вернуть значение current после завершения итерации. 😎 Решение:
class Solution:
def fib(self, N: int) -> int:
if N <= 1:
return N
current, prev1, prev2 = 0, 1, 0
for _ in range(2, N + 1):
current = prev1 + prev2
prev2, prev1 = prev1, current
return current
Ставь 👍 и забирай 📚 Базу знаний8 922
MBA онлайн с аккредитацией и беспроцентной рассрочкой!
Готов к карьерному рывку?
Обучайся на программе MBA с международной аккредитацией и выйди на новый уровень карьеры!
✅ Форматы: онлайн и офлайн
✅ 37+ направлений
✅ Актуальные программы 2025 года
✅ Диплом за 1 год
✅ Беспроцентная рассрочка
Не жди — запишись уже сегодня и начни свой путь к успеху!
Стань лидером уже сейчас!
Только до конца года
Скидки до -45% на обучение в Московской Академии Бизнеса!
Перейти на сайт
#реклама 16+
moscow.mba
О рекламодателе
8 922
#medium
Задача: 508. Most Frequent Subtree Sum
Дано корень бинарного дерева, вернуть наиболее часто встречающуюся сумму поддерева. Если есть несколько таких значений, вернуть все значения с наибольшей частотой в любом порядке.
Сумма поддерева узла определяется как сумма всех значений узлов, образованных поддеревом, укорененным в этом узле (включая сам узел).
Пример:
Input: root = [5,2,-3] Output: [2,-3,4]👨💻 Алгоритм: 1⃣Инициализация переменных Инициализируйте переменные sumFreq для хранения частоты всех сумм поддеревьев. Инициализируйте maxFreq для хранения максимальной частоты. Создайте массив maxFreqSums для хранения всех сумм поддеревьев, частота которых равна максимальной. 2⃣Обход дерева и вычисление сумм Выполните обход дерева в порядке post-order. Используйте суммы поддеревьев левого и правого дочерних узлов для вычисления суммы текущего поддерева. Увеличьте частоту текущей суммы в sumFreq. Обновите maxFreq, если частота текущей суммы больше текущего maxFreq. 3⃣Сборка результата Пройдитесь по sumFreq и добавьте все суммы с частотой, равной maxFreq, в массив maxFreqSums. Верните массив maxFreqSums. 😎 Решение:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def findFrequentTreeSum(self, root: TreeNode) -> List[int]:
from collections import defaultdict
sumFreq = defaultdict(int)
maxFreq = 0
def subtreeSum(node):
nonlocal maxFreq
if not node:
return 0
leftSum = subtreeSum(node.left)
rightSum = subtreeSum(node.right)
currSum = node.val + leftSum + rightSum
sumFreq[currSum] += 1
maxFreq = max(maxFreq, sumFreq[currSum])
return currSum
subtreeSum(root)
return [s for s in sumFreq if sumFreq[s] == maxFreq]
Ставь 👍 и забирай 📚 Базу знаний8 922
#easy
Задача: 507. Perfect Number
Совершенное число — это положительное целое число, которое равно сумме своих положительных делителей, исключая само число. Делитель целого числа x — это целое число, которое может делить x нацело.
Дано целое число n, верните true, если n является совершенным числом, в противном случае верните false.
Пример:
Input: num = 28 Output: true Explanation: 28 = 1 + 2 + 4 + 7 + 14 1, 2, 4, 7, and 14 are all divisors of 28.👨💻 Алгоритм: 1⃣Инициализация Если число num меньше или равно 0, вернуть false. Инициализируйте переменную sum значением 0. 2⃣Поиск делителей и вычисление суммы Переберите числа от 1 до квадратного корня num. Если число является делителем num, добавьте его к sum. Если делитель не равен квадратному корню num, добавьте к sum также результат деления num на делитель. 3⃣Проверка на совершенное число Вычтите num из sum. Если результат равен num, вернуть true, иначе вернуть false. 😎 Решение:
class Solution:
def checkPerfectNumber(self, num: int) -> bool:
if num <= 0:
return False
sum_ = 0
for i in range(1, int(num ** 0.5) + 1):
if num % i == 0:
sum_ += i
if i * i != num:
sum_ += num // i
return sum_ - num == num
Ставь 👍 и забирай 📚 Базу знаний8 922
Запустите рекламу в телеграм-каналах с Яндекс Директом
Перфоманс-реклама теперь в телеграм-каналах ⚡
Яндекс Директ знает, как привлечь целевую аудиторию 💰👌
Попробовать
#реклама
yandex.ru
О рекламодателе
8 922
#easy
Задача: 506. Relative Ranks
Вам дан целочисленный массив score размером n, где score[i] — это результат i-го спортсмена на соревновании. Все результаты гарантированно уникальны.
Спортсмены размещаются на основе своих результатов: спортсмен, занявший 1-е место, имеет наивысший результат, спортсмен, занявший 2-е место, имеет второй по величине результат и так далее. Размещение каждого спортсмена определяет его ранг:
Ранг спортсмена, занявшего 1-е место, — "Gold Medal".
Ранг спортсмена, занявшего 2-е место, — "Silver Medal".
Ранг спортсмена, занявшего 3-е место, — "Bronze Medal".
Для спортсменов, занявших с 4-го по n-е место, их ранг соответствует их номеру в размещении (т.е. ранг спортсмена, занявшего x-е место, — "x").
Верните массив answer размером n, где answer[i] — это ранг i-го спортсмена.
Пример:
Input: score = [5,4,3,2,1] Output: ["Gold Medal","Silver Medal","Bronze Medal","4","5"] Explanation: The placements are [1st, 2nd, 3rd, 4th, 5th].👨💻 Алгоритм: 1⃣Инициализация и нахождение максимального значения Инициализируйте переменную N длиной массива score. Определите функцию findMax, которая находит максимальный балл в массиве score. 2⃣Создание вспомогательных структур Инициализируйте массив scoreToIndex размером M + 1, где M — это максимальное значение в массиве score. Заполните scoreToIndex таким образом, чтобы для каждого score[i] его индекс сохранялся в scoreToIndex[score[i]]. 3⃣Присваивание рангов и формирование ответа Создайте массив rank для хранения рангов спортсменов. Используйте цикл для присваивания медалей и рангов в зависимости от значений в scoreToIndex, начиная с наибольшего. 😎 Решение:
class Solution:
def findRelativeRanks(self, score: List[int]) -> List[str]:
N = len(score)
max_score = max(score)
score_to_index = [0] * (max_score + 1)
for i, s in enumerate(score):
score_to_index[s] = i + 1
MEDALS = ["Gold Medal", "Silver Medal", "Bronze Medal"]
rank = [""] * N
place = 1
for i in range(max_score, -1, -1):
if score_to_index[i] != 0:
original_index = score_to_index[i] - 1
if place < 4:
rank[original_index] = MEDALS[place - 1]
else:
rank[original_index] = str(place)
place += 1
return rank
Ставь 👍 и забирай 📚 Базу знаний8 922
#medium
Задача: 505. The Maze II
В лабиринте есть мячик с пустыми пространствами (обозначенными как 0) и стенами (обозначенными как 1). Мячик может перемещаться через пустые пространства, катясь вверх, вниз, влево или вправо, но он не остановится, пока не столкнется со стеной. Когда мячик останавливается, он может выбрать следующее направление.
Дан лабиринт размером m x n, начальная позиция мяча и пункт назначения, где start = [startrow, startcol] и destination = [destinationrow, destinationcol]. Верните кратчайшее расстояние, на которое мячик должен остановиться в пункте назначения. Если мячик не может остановиться в пункте назначения, верните -1.
Расстояние — это количество пройденных пустых пространств мячиком от начальной позиции (исключительно) до пункта назначения (включительно).
Предположим, что границы лабиринта — это стены. В примере ниже они не указаны.
Пример:
Input: maze = [[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]], start = [0,4], destination = [4,4] Output: 12 Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right. The length of the path is 1 + 1 + 3 + 1 + 2 + 2 + 2 = 12.👨💻 Алгоритм: 1⃣Инициализация Создайте массив distance для хранения минимальных расстояний до каждой позиции, инициализируйте его большими значениями. Установите начальную позицию start на нулевое расстояние и добавьте её в очередь. 2⃣Обход лабиринта Используйте очередь для выполнения обхода в ширину (BFS). Для каждой позиции извлеките из очереди текущую позицию и исследуйте все возможные направления до столкновения со стеной, отслеживая количество шагов. 3⃣Обновление расстояний Если достигнутая новая позиция может быть достигнута меньшим числом шагов, обновите distance и добавьте эту позицию в очередь. После завершения обхода верните минимальное расстояние до пункта назначения или -1, если его нельзя достичь. 😎 Решение:
from collections import deque
class Solution:
def shortestDistance(self, maze: List[List[int]], start: List[int], destination: List[int]) -> int:
m, n = len(maze), len(maze[0])
distance = [[float('inf')] * n for _ in range(m)]
distance[start[0]][start[1]] = 0
directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
queue = deque([start])
while queue:
s = queue.popleft()
for dx, dy in directions:
x, y, count = s[0] + dx, s[1] + dy, 0
while 0 <= x < m and 0 <= y < n and maze[x][y] == 0:
x += dx
y += dy
count += 1
x -= dx
y -= dy
if distance[s[0]][s[1]] + count < distance[x][y]:
distance[x][y] = distance[s[0]][s[1]] + count
queue.append([x, y])
return -1 if distance[destination[0]][destination[1]] == float('inf') else distance[destination[0]][destination[1]]
Ставь 👍 и забирай 📚 Базу знаний8 922
Миграция в облако? Это легко!
Собственная инфраструктура устарела или не справляется с нагрузками? Используйте облачные ресурсы! Эксперты Yandex Cloud помогут перейти в облако быстро, легко и безопасно.
✅ Мы полностью сопровождаем процесс.
✅ От вас — только инженер с доступом к инфраструктуре.
✅ Архитектура под ваши задачи, миграция и поддержка на каждом шагу — всё включено.
⚡Переходите в Yandex Cloud и забудьте о старом железе. А если успеете подать заявку до 28 февраля, мы покроем расходы на инженеров и тестовую инфраструктуру.
Подать заявку
#реклама 16+
yandex.cloud
О рекламодателе
Реклама на Яндексе
8 922
#medium
Задача: 503. Next Greater Element II
Дан циклический массив целых чисел nums (т.е. следующий элемент после nums[nums.length - 1] это nums[0]), верните следующее большее число для каждого элемента в nums.
Следующее большее число для числа x — это первое большее число, следующее за ним в порядке обхода массива, что означает, что вы можете искать циклически, чтобы найти следующее большее число. Если оно не существует, верните -1 для этого числа.
Пример:
Input: nums = [1,2,1] Output: [2,-1,2] Explanation: The first 1's next greater number is 2; The number 2 can't find next greater number. The second 1's next greater number needs to search circularly, which is also 2.👨💻 Алгоритм: 1⃣Инициализация Создайте массив res той же длины, что и nums, и заполните его значениями -1. 2⃣Поиск следующего большего элемента Для каждого элемента nums[i], используя индекс j, ищите следующий больший элемент среди следующих (циклически) n-1 элементов. Если найден больший элемент, обновите res[i] и прервите внутренний цикл. 3⃣Возврат результата Верните массив res. 😎 Решение:
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
n = len(nums)
res = [-1] * n
for i in range(n):
for j in range(1, n):
if nums[(i + j) % n] > nums[i]:
res[i] = nums[(i + j) % n]
break
return res
Ставь 👍 и забирай 📚 Базу знаний8 922
#hard
Задача: 502. IPO
Предположим, что LeetCode скоро начнет свое IPO. Чтобы продать свои акции по хорошей цене венчурным капиталистам, LeetCode хочет выполнить несколько проектов для увеличения своего капитала перед IPO. Поскольку у компании ограниченные ресурсы, она может завершить не более k различных проектов до IPO. Помогите LeetCode разработать лучший способ максимизации общего капитала после завершения не более k различных проектов.
Вам дано n проектов, где i-й проект имеет чистую прибыль profits[i] и требует минимального капитала capital[i] для его начала.
Изначально у вас есть капитал w. Когда вы завершаете проект, вы получаете его чистую прибыль, и эта прибыль добавляется к вашему общему капиталу.
Выберите список из не более чем k различных проектов из данных, чтобы максимально увеличить ваш конечный капитал, и верните окончательно максимизированный капитал.
Ответ гарантированно поместится в 32-битное целое число со знаком.
Пример:
Input: k = 2, w = 0, profits = [1,2,3], capital = [0,1,1] Output: 4 Explanation: Since your initial capital is 0, you can only start the project indexed 0. After finishing it you will obtain profit 1 and your capital becomes 1. With capital 1, you can either start the project indexed 1 or the project indexed 2. Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4.👨💻 Алгоритм: 1⃣Сортировка и инициализация Отсортируйте проекты по возрастанию капитала. Создайте указатель ptr на первый недоступный проект в отсортированном массиве. Создайте приоритетную очередь для прибылей доступных проектов. Изначально очередь пуста. 2⃣Выбор проектов Выполните следующие действия k раз: добавьте в приоритетную очередь прибыли новых доступных проектов. Перемещайте указатель по отсортированному массиву, когда проекты становятся доступными. Если приоритетная очередь пуста, завершите алгоритм. 3⃣Увеличение капитала Максимальное значение в приоритетной очереди — это прибыль проекта, который будет запущен сейчас. Увеличьте капитал на это значение. Удалите его из очереди, так как он больше не может быть использован. 😎 Решение:
import heapq
class Solution:
def findMaximizedCapital(self, k: int, w: int, profits: List[int], capital: List[int]) -> int:
projects = sorted(zip(capital, profits))
max_heap = []
ptr = 0
for _ in range(k):
while ptr < len(projects) and projects[ptr][0] <= w:
heapq.heappush(max_heap, -projects[ptr][1])
ptr += 1
if not max_heap:
break
w -= heapq.heappop(max_heap)
return w
Ставь 👍 и забирай 📚 Базу знаний8 922
Битрикс24
💻Один онлайн-сервис для совместной работы.
📱10+ инструментов.
✅0 денег.
Счастливые сотрудники. Прибыльный бизнес.
Регистрируйтесь и забирайте себе
Зарегистрироваться
#реклама 16+
office-online.bitrix24.ru
О рекламодателе
8 922
#easy
Задача: 501. Find Mode in Binary Search Tree
Дано корень бинарного дерева поиска (BST) с дубликатами. Необходимо вернуть все моды (т.е. самые часто встречающиеся элементы) в этом дереве.
Если в дереве более одной моды, верните их в любом порядке.
Предположим, что BST определяется следующим образом:
Левое поддерево узла содержит только узлы с ключами, меньшими или равными ключу этого узла.
Правое поддерево узла содержит только узлы с ключами, большими или равными ключу этого узла.
Оба поддерева также должны быть бинарными деревьями поиска.
Пример:
Input: root = [1,null,2,2] Output: [2]👨💻 Алгоритм: 1⃣Обход дерева Выполните обход дерева (inorder DFS) с использованием рекурсивной функции dfs, чтобы пройти по всем узлам дерева. На каждом узле добавьте node.val в список values. 2⃣Поиск мод Инициализируйте переменные maxStreak, currStreak, currNum как 0 и пустой список ans. Пройдите по списку values. Для каждого числа num: если num равно currNum, увеличьте currStreak. Иначе, установите currStreak равным 1, а currNum равным num. Если currStreak больше maxStreak, обновите maxStreak и сбросьте ans. Если currStreak равен maxStreak, добавьте num в ans. 3⃣Возврат результата Верните список ans. 😎 Решение:
class Solution:
def findMode(self, root: TreeNode) -> List[int]:
values = []
self.dfs(root, values)
max_streak = curr_streak = curr_num = 0
ans = []
for num in values:
if num == curr_num:
curr_streak += 1
else:
curr_streak = 1
curr_num = num
if curr_streak > max_streak:
ans = [num]
max_streak = curr_streak
elif curr_streak == max_streak:
ans.append(num)
return ans
def dfs(self, node, values):
if not node:
return
self.dfs(node.left, values)
values.append(node.val)
self.dfs(node.right, values)
Ставь 👍 и забирай 📚 Базу знаний8 922
Канал про IT и Ботов
Мемчики, фичи и тг боты – то, что обсуждают на этом канале 📱
🖥 Ждем тебя: @sudoteach
8 922
Repost from easyoffer
💡 В EasyOffer 2.0 появится фильтрация вопросов по грейдам и типам интервью!
📊 Например, вот вероятности ТОП-30 вопросов, которые задают на HR-скрининге Python-разработчику уровня Middle/Senior. Данные основаны на 53 реальных интервью.
97% Какие у тебя зарплатные ожидания
73% Какие у тебя есть вопросы
44% Какие критерии при выборе будущей работы
41% Расскажи о себе
38% Почему ищешь работу
35% Расскажи про свой опыт
35% Расскажи про проект на предыдущей работе
32% Почему уволился с предыдущей работы
29% Где территориально сейчас живешь/находишься
23% Есть ли другие предложения по работе
17% Есть ли военный билет
17% Почему хочешь сменить работу
17% Как проводишь свободное время
17% Расскажи про задачи на предыдущей работе
17% Сколько коммерческого опыта работы с Python
17% С какими БД работал
14% Находишься ли в активном поиске работы
14% С каким стеком работаешь
14% Почему решил откликнуться на нашу вакансию
14% Какой текущий статус поиска работы
11% Почему решил стать программистом
11% С какими фреймворками работал
11% Какую зарплату получал на предыдущей работе
11% Работаешь ли в настоящий момент
11% На какой грейд себя оцениваешь
11% Как быстро можешь приступить к работе после получения офера
11% Расскажи про свои pet-проекты
8% Какие знаешь типы данных в Python
8% Что такое декоратор в Python
8% Что ищешь на новой работе
🚀 Скоро стартует краудфандинговая кампания, которая поможет ускорить разработку EasyOffer 2.0.
Первые спонсоры получат уникальные лимитированные награды!
📢 Если вам это интересно, подписывайтесь на канал 👉 этот телеграм канал
8 922
#hard
Задача: 499. The Maze III
В лабиринте есть мячик с пустыми пространствами (0) и стенами (1). Мячик может катиться вверх, вниз, влево или вправо, пока не столкнется со стеной, затем выбрать новое направление. В лабиринте также есть отверстие, куда мячик упадет, если закатится в него.
Дан лабиринт размером m x n, позиция мяча ball и отверстия hole, где ball = [ballrow, ballcol] и hole = [holerow, holecol]. Верните строку instructions с кратчайшим путем мячика к отверстию. Если существует несколько вариантов, верните лексикографически минимальный. Если путь невозможен, верните "impossible". Ответ должен содержать 'u' (вверх), 'd' (вниз), 'l' (влево) и 'r' (вправо).
Расстояние — это количество пройденных пустых пространств от начальной позиции (исключительно) до конечной (включительно).
Вы можете предположить, что границы лабиринта — это стены. В примере ниже они не указаны.
Пример:
Input: maze = [[0,0,0,0,0],[1,1,0,0,1],[0,0,0,0,0],[0,1,0,0,1],[0,1,0,0,0]], ball = [4,3], hole = [0,1] Output: "lul"👨💻 Алгоритм: 1⃣Инициализация и вспомогательные функции Создайте функцию valid для проверки, находится ли координата (row, col) в пределах лабиринта и является ли она пустым пространством. Создайте функцию getNeighbors для получения списка соседей для данной позиции. Двигайтесь в каждом направлении (вверх, вниз, влево, вправо) до встречи со стеной. 2⃣Запуск алгоритма Дейкстры Инициализируйте очередь с начальной позицией мяча, где элементы с меньшим расстоянием имеют высокий приоритет, а при равных расстояниях выбирайте минимальную строку пути. Создайте структуру seen для отслеживания посещенных узлов. 3⃣Поиск кратчайшего пути Пока очередь не пуста, извлекайте узел с наименьшим расстоянием. Если узел посещен, пропустите его. Если это отверстие, верните текущий путь. Отметьте узел как посещенный, добавьте его соседей в очередь, обновив расстояние и путь. Если пути нет, верните "impossible". 😎 Решение:
import heapq
class State:
def __init__(self, r, c, d, p):
self.row = r
self.col = c
self.dist = d
self.path = p
def __lt__(self, other):
return self.dist == other.dist and self.path < other.path or self.dist < other.dist
class Solution:
def findShortestWay(self, maze, ball, hole):
m, n = len(maze), len(maze[0])
directions = [(0, -1), (-1, 0), (0, 1), (1, 0)]
textDirections = ["l", "u", "r", "d"]
heap = []
heapq.heappush(heap, State(ball[0], ball[1], 0, ""))
seen = [[False] * n for _ in range(m)]
while heap:
curr = heapq.heappop(heap)
if seen[curr.row][curr.col]:
continue
if [curr.row, curr.col] == hole:
return curr.path
seen[curr.row][curr.col] = True
for nextState in self.getNeighbors(curr.row, curr.col, maze, hole, directions, textDirections):
heapq.heappush(heap, State(nextState.row, nextState.col, curr.dist + nextState.dist, curr.path + nextState.path))
return "impossible"
def getNeighbors(self, row, col, maze, hole, directions, textDirections):
m, n = len(maze), len(maze[0])
neighbors = []
for i in range(4):
dy, dx = directions[i]
direction = textDirections[i]
currRow, currCol, dist = row, col, 0
while 0 <= currRow + dy < m and 0 <= currCol + dx < n and maze[currRow + dy][currCol + dx] == 0:
currRow += dy
currCol += dx
dist += 1
if [currRow, currCol] == hole:
break
neighbors.append(State(currRow, currCol, dist, direction))
return neighbors
Ставь 👍 и забирай 📚 Базу знаний8 922
Дарим подписку на Яндекс Музыку
Ответьте на 1 вопрос и Яндекс Музыка для вас и 3-х ваших близких 30 дней бесплатно.
Кинопоиск и Яндекс Книги тоже в подписке.
Попробуйте сейчас❤️
Попробовать
#реклама 18+
music.yandex.ru
О рекламодателе
Реклама на Яндексе
