Python | LeetCode
Open in Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv
Show more9 125
Subscribers
-324 hours
-367 days
-9630 days
Posts Archive
9 125
#easy
Задача: 283. Move Zeroes
Дан целочисленный массив nums. Переместите все нули в конец массива, сохраняя относительный порядок ненулевых элементов.
Обратите внимание, что вы должны сделать это на месте, не создавая копию массива.
Пример:
Input: nums = [0,1,0,3,12] Output: [1,3,12,0,0]👨💻 Алгоритм: 1⃣Инициализация указателей: Инициализируйте два указателя: lastNonZeroFoundAt для отслеживания позиции последнего ненулевого элемента и cur для итерации по массиву. 2⃣Итерация и обмен элементами: Итерируйтесь по массиву с помощью указателя cur. Если текущий элемент ненулевой, поменяйте его местами с элементом, на который указывает lastNonZeroFoundAt, и продвиньте указатель lastNonZeroFoundAt. 3⃣Завершение итерации: Повторяйте шаг 2 до конца массива. В итоге все нули будут перемещены в конец массива, сохраняя относительный порядок ненулевых элементов. 😎 Решение:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
lastNonZeroFoundAt = 0
for cur in range(len(nums)):
if nums[cur] != 0:
nums[lastNonZeroFoundAt], nums[cur] = nums[cur], nums[lastNonZeroFoundAt]
lastNonZeroFoundAt += 1
Ставь 👍 и забирай 📚 Базу знаний9 125
#hard
Задача: 282. Expression Add Operators
Дана строка num, содержащая только цифры, и целое число target. Верните все возможные варианты вставки бинарных операторов '+', '-', и/или '*' между цифрами строки num так, чтобы результирующее выражение вычислялось в значение target.
Учтите, что операнды в возвращаемых выражениях не должны содержать ведущих нулей.
Пример:
Input: num = "232", target = 8 Output: ["2*3+2","2+3*2"] Explanation: Both "2*3+2" and "2+3*2" evaluate to 8.👨💻 Алгоритм: 1⃣Инициализация и рекурсивный вызов: Создайте класс Solution с полями для хранения результирующих выражений, строки цифр и целевого значения. Инициализируйте эти поля в методе addOperators и запустите рекурсивный метод для генерации всех возможных выражений. 2⃣Рекурсивная генерация выражений: В методе recurse на каждом шаге рассматривайте текущий индекс, предыдущий операнд, текущий операнд и текущее значение выражения. Обрабатывайте все возможные операторы: без оператора (расширение текущего операнда), сложение, вычитание и умножение. На каждом шаге обновляйте текущее значение и выражение. 3⃣Проверка и запись валидных выражений: Когда вся строка цифр обработана, проверяйте, соответствует ли итоговое значение целевому значению и нет ли остатков операндов. Если выражение валидное, записывайте его в список результатов. 😎 Решение:
class Solution:
def __init__(self):
self.answer = []
self.digits = ""
self.target = 0
def recurse(self, index, previous_operand, current_operand, value, ops):
if index == len(self.digits):
if value == self.target and current_operand == 0:
self.answer.append("".join(ops[1:]))
return
current_operand = current_operand * 10 + int(self.digits[index])
str_operand = str(current_operand)
if current_operand > 0:
self.recurse(index + 1, previous_operand, current_operand, value, ops)
ops.append("+")
ops.append(str_operand)
self.recurse(index + 1, current_operand, 0, value + current_operand, ops)
ops.pop()
ops.pop()
if ops:
ops.append("-")
ops.append(str_operand)
self.recurse(index + 1, -current_operand, 0, value - current_operand, ops)
ops.pop()
ops.pop()
ops.append("*")
ops.append(str_operand)
self.recurse(index + 1, current_operand * previous_operand, 0, value - previous_operand + (current_operand * previous_operand), ops)
ops.pop()
ops.pop()
def addOperators(self, num, target):
if not num:
return []
self.target = target
self.digits = num
self.answer = []
self.recurse(0, 0, 0, 0, [])
return self.answer
Ставь 👍 и забирай 📚 Базу знаний9 125
#medium
Задача: 281. Zigzag Iterator
Даны два вектора целых чисел v1 и v2, реализуйте итератор, который возвращает их элементы поочередно.
Реализуйте класс ZigzagIterator:
ZigzagIterator(List<int> v1, List<int> v2) инициализирует объект с двумя векторами v1 и v2.
boolean hasNext() возвращает true, если в итераторе еще есть элементы, и false в противном случае.
int next() возвращает текущий элемент итератора и перемещает итератор к следующему элементу.
Пример:
Input: v1 = [1,2], v2 = [3,4,5,6] Output: [1,3,2,4,5,6] Explanation: By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,3,2,4,5,6].👨💻 Алгоритм: 1⃣Инициализация объекта: Создайте класс ZigzagIterator с двумя списками v1 и v2. Сохраните эти списки в структуре vectors. Инициализируйте очередь queue, содержащую пары индексов: индекс списка и индекс элемента в этом списке, если список не пуст. 2⃣Метод next: Удалите первую пару индексов из очереди. Извлеките элемент из соответствующего списка по указанным индексам. Если в текущем списке есть еще элементы, добавьте новую пару индексов (тот же список, следующий элемент) в конец очереди. Верните извлеченный элемент. 3⃣Метод hasNext: Проверьте, пуста ли очередь. Верните true, если в очереди есть элементы, и false в противном случае. 😎 Решение:
from collections import deque
class ZigzagIterator:
def __init__(self, v1, v2):
self.vectors = [v1, v2]
self.queue = deque((i, 0) for i, vec in enumerate(self.vectors) if vec)
def next(self):
vecIndex, elemIndex = self.queue.popleft()
if elemIndex + 1 < len(self.vectors[vecIndex]):
self.queue.append((vecIndex, elemIndex + 1))
return self.vectors[vecIndex][elemIndex]
def hasNext(self):
return bool(self.queue)
Ставь 👍 и забирай 📚 Базу знаний9 125
#easy
Задача: 293. Flip Game
Вы играете в игру Flip со своим другом.
Вам дана строка currentState, которая содержит только символы '+' и '-'. Вы и ваш друг по очереди переворачиваете две последовательные "++" в "--". Игра заканчивается, когда один из игроков больше не может сделать ход, и, следовательно, другой игрок становится победителем.
Верните все возможные состояния строки currentState после одного допустимого хода. Вы можете вернуть ответы в любом порядке. Если допустимых ходов нет, верните пустой список [].
Пример:
Input: currentState = "++++" Output: ["--++","+--+","++--"]👨💻 Алгоритм: 1⃣Создайте пустой массив nextPossibleStates для хранения всех возможных следующих состояний после одного хода. 2⃣Запустите цикл от index = 0 до currentState.size() - 1. Для каждого индекса: Если символы на позициях index и index + 1 равны '+': Создайте новую строку nextState, заменив две последовательные '+' на '--'. Используйте конкатенацию строк для создания nextState из подстроки до первого '+', "--" и подстроки после второго '+' до конца. Сохраните созданное nextState в массив nextPossibleStates. 3⃣После цикла верните массив nextPossibleStates, содержащий все возможные следующие состояния. 😎 Решение:
class Solution:
def generatePossibleNextMoves(self, currentState: str) -> list[str]:
nextPossibleStates = []
for index in range(len(currentState) - 1):
if currentState[index] == "+" and currentState[index + 1] == "+":
nextState = currentState[:index] + "--" + currentState[index + 2:]
nextPossibleStates.append(nextState)
return nextPossibleStates
Ставь 👍 и забирай 📚 Базу знаний9 125
#medium
Задача: 291. Word Pattern II
Дан шаблон и строка s, вернуть true, если строка s соответствует шаблону.
Строка s соответствует шаблону, если существует биективное отображение отдельных символов на непустые строки так, что если каждый символ в шаблоне заменить на строку, которой он отображается, то результирующая строка будет равна s. Биективное отображение означает, что ни два символа не отображаются на одну и ту же строку, и ни один символ не отображается на две разные строки.
Пример:
Input: pattern = "abab", s = "redblueredblue" Output: true Explanation: One possible mapping is as follows: 'a' -> "red" 'b' -> "blue"👨💻 Алгоритм: 1⃣Инициализация структур данных и определение рекурсивной функции: Создайте хеш-таблицу symbolMap для отображения символов шаблона на подстроки строки s. Создайте множество wordSet для хранения уникальных подстрок строки s, которые были отображены на символ. Определите рекурсивную функцию isMatch, принимающую индексы в строке s (sIndex) и в шаблоне (pIndex), чтобы определить, соответствует ли строка s шаблону. 2⃣Рекурсивная проверка соответствия: Базовый случай: если pIndex равно длине шаблона, верните true, если sIndex равно длине строки s; иначе верните false. Получите символ из шаблона по индексу pIndex. Если символ уже ассоциирован с подстрокой, проверьте, совпадают ли следующие символы в строке s с этой подстрокой. Если нет, верните false. Если совпадают, вызовите isMatch для следующего символа в шаблоне. 3⃣Отображение новых подстрок: Если символ новый, попробуйте сопоставить его с новыми подстроками строки s, начиная с sIndex и до конца строки. Для каждой новой подстроки проверьте, существует ли она уже в ` 😎 Решение:
class Solution:
def wordPatternMatch(self, pattern: str, s: str) -> bool:
symbol_map = {}
word_set = set()
return self.is_match(s, 0, pattern, 0, symbol_map, word_set)
def is_match(self, s, s_index, pattern, p_index, symbol_map, word_set):
if p_index == len(pattern):
return s_index == len(s)
symbol = pattern[p_index]
if symbol in symbol_map:
word = symbol_map[symbol]
if not s.startswith(word, s_index):
return False
return self.is_match(s, s_index + len(word), pattern, p_index + 1, symbol_map, word_set)
for k in range(s_index + 1, len(s) + 1):
new_word = s[s_index:k]
if new_word in word_set:
continue
symbol_map[symbol] = new_word
word_set.add(new_word)
if self.is_match(s, k, pattern, p_index + 1, symbol_map, word_set):
return True
del symbol_map[symbol]
word_set.remove(new_word)
return False
Ставь 👍 и забирай 📚 Базу знаний9 125
#easy
Задача: 292. Nim Game
Вы играете в следующую игру Nim со своим другом:
Изначально на столе лежит куча камней.
Вы и ваш друг поочередно делаете ходы, и вы ходите первым.
Каждый ход игрок, чей ход, будет убирать от 1 до 3 камней из кучи.
Тот, кто убирает последний камень, становится победителем.
Дано n, количество камней в куче. Верните true, если вы можете выиграть игру, предполагая, что и вы, и ваш друг играете оптимально, иначе верните false.
Пример:
Input: n = 4 Output: false Explanation: These are the possible outcomes: 1. You remove 1 stone. Your friend removes 3 stones, including the last stone. Your friend wins. 2. You remove 2 stones. Your friend removes 2 stones, including the last stone. Your friend wins. 3. You remove 3 stones. Your friend removes the last stone. Your friend wins. In all outcomes, your friend wins.👨💻 Алгоритм: 1⃣Определите базовый случай: Если количество камней n меньше или равно 3, вы всегда можете выиграть, убрав все камни. В этом случае верните true. 2⃣Анализ оставшихся камней: Если количество камней n делится на 4 без остатка (n % 4 == 0), вы не можете выиграть, так как независимо от вашего хода ваш друг всегда сможет оставить вам кратное 4 количество камней. В этом случае верните false. 3⃣Выигрышная стратегия: Если количество камней n не кратно 4 (n % 4 != 0), вы можете выиграть, оставляя вашему другу кратное 4 количество камней после вашего хода. В этом случае верните true. 😎 Решение:
class Solution:
def canWinNim(self, n: int) -> bool:
return n % 4 != 0
Ставь 👍 и забирай 📚 Базу знаний9 125
#medium
Задача: 294. Flip Game II
Вы играете в игру Flip со своим другом.
Вам дана строка currentState, которая содержит только символы '+' и '-'. Вы и ваш друг по очереди переворачиваете две последовательные "++" в "--". Игра заканчивается, когда игрок больше не может сделать ход, и, следовательно, другой игрок становится победителем.
Верните true, если начальный игрок может гарантировать победу, и false в противном случае.
Пример:
Input: currentState = "++++" Output: true Explanation: The starting player can guarantee a win by flipping the middle "++" to become "+--+".👨💻 Алгоритм: 1⃣Генерация всех возможных следующих ходов: Для текущего состояния currentState, создайте все возможные новые состояния, заменяя каждую пару "++" на "--". 2⃣Рекурсивная проверка выигрыша: Для каждого нового состояния вызовите функцию рекурсивно, чтобы проверить, может ли противник проиграть в этом новом состоянии. Если противник не может сделать ход, верните true, так как начальный игрок гарантирует победу. 3⃣Проверка всех возможных ходов: Если для всех возможных ходов начальный игрок не может гарантировать победу, верните false. Иначе, если есть хотя бы один ход, при котором противник проигрывает, верните true. 😎 Решение:
class Solution:
def canWin(self, currentState: str) -> bool:
stateArray = list(currentState)
for i in range(len(stateArray) - 1):
if stateArray[i] == '+' and stateArray[i + 1] == '+':
stateArray[i] = '-'
stateArray[i + 1] = '-'
newState = ''.join(stateArray)
if not self.canWin(newState):
stateArray[i] = '+'
stateArray[i + 1] = '+'
return True
stateArray[i] = '+'
stateArray[i + 1] = '+'
return False
Ставь 👍 и забирай 📚 Базу знаний9 125
#hard
Задача: 295. Find Median from Data Stream
Медиана — это среднее значение в упорядоченном списке целых чисел. Если размер списка четный, то медианы нет, и медиана — это среднее арифметическое двух средних значений.
Например, для arr = [2, 3, 4] медиана равна 3.
Например, для arr = [2, 3] медиана равна (2 + 3) / 2 = 2.5.
Реализуйте класс MedianFinder:
MedianFinder() инициализирует объект MedianFinder.
void addNum(int num) добавляет целое число num из потока данных в структуру данных.
double findMedian() возвращает медиану всех элементов на данный момент. Ответы с точностью до 10^-5 от фактического ответа будут приниматься.
Пример:
Input ["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] [[], [1], [2], [], [3], []] Output [null, null, null, 1.5, null, 2.0] Explanation MedianFinder medianFinder = new MedianFinder(); medianFinder.addNum(1); // arr = [1] medianFinder.addNum(2); // arr = [1, 2] medianFinder.findMedian(); // return 1.5 (i.e., (1 + 2) / 2) medianFinder.addNum(3); // arr[1, 2, 3] medianFinder.findMedian(); // return 2.0👨💻 Алгоритм: 1⃣Храните числа в контейнере с возможностью изменения размера: Создайте массив для хранения чисел. 2⃣Добавление нового числа: Добавьте новое число в массив. 3⃣Вычисление и вывод медианы: Отсортируйте массив. Если размер массива нечетный, верните среднее значение массива. Если размер массива четный, верните среднее арифметическое двух средних значений массива. 😎 Решение:
class MedianFinder:
def __init__(self):
self.numbers = []
def addNum(self, num: int) -> None:
self.numbers.append(num)
def findMedian(self) -> float:
self.numbers.sort()
n = len(self.numbers)
if n % 2 == 0:
return (self.numbers[n // 2 - 1] + self.numbers[n // 2]) / 2.0
else:
return float(self.numbers[n // 2])
Ставь 👍 и забирай 📚 Базу знаний9 125
#hard
Задача: 296. Best Meeting Point
Дан бинарный сетка размером m x n, где каждая 1 обозначает дом одного друга. Верните минимальное общее расстояние путешествия.
Общее расстояние путешествия — это сумма расстояний между домами друзей и точкой встречи.
Расстояние рассчитывается по Манхэттенскому расстоянию, где distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.
Пример:
Input: grid = [[1,0,0,0,1],[0,0,0,0,0],[0,0,1,0,0]] Output: 6 Explanation: Given three friends living at (0,0), (0,4), and (2,2). The point (0,2) is an ideal meeting point, as the total travel distance of 2 + 2 + 2 = 6 is minimal. So return 6.👨💻 Алгоритм: 1⃣Определение координат домов: Пройдите по сетке и соберите координаты всех домов (ячейки с значением 1) в два списка: один для координат x и один для координат y. 2⃣Нахождение медианы: Отсортируйте списки координат x и y. Найдите медианы в обоих списках. Медианы координат x и y укажут оптимальную точку встречи. 3⃣Вычисление минимального общего расстояния: Вычислите сумму Манхэттенских расстояний от каждого дома до точки встречи, используя найденные медианы в качестве координат точки встречи. Верните это значение как минимальное общее расстояние путешествия. 😎 Решение:
class Solution:
def minTotalDistance(self, grid: list[list[int]]) -> int:
minDistance = float('inf')
for row in range(len(grid)):
for col in range(len(grid[0])):
distance = self.search(grid, row, col)
minDistance = min(distance, minDistance)
return minDistance
def search(self, grid: list[list[int]], row: int, col: int) -> int:
q = [(row, col, 0)]
m = len(grid)
n = len(grid[0])
visited = [[False] * n for _ in range(m)]
totalDistance = 0
while q:
r, c, d = q.pop(0)
if r < 0 or c < 0 or r >= m or c >= n or visited[r][c]:
continue
if grid[r][c] == 1:
totalDistance += d
visited[r][c] = True
q.append((r + 1, c, d + 1))
q.append((r - 1, c, d + 1))
q.append((r, c + 1, d + 1))
q.append((r, c - 1, d + 1))
return totalDistance
Ставь 👍 и забирай 📚 Базу знаний9 125
#hard
Задача: 297. Serialize and Deserialize Binary Tree
Сериализация — это процесс преобразования структуры данных или объекта в последовательность битов, чтобы их можно было сохранить в файле или буфере памяти или передать по сетевому соединению для последующего восстановления в той же или другой компьютерной среде.
Разработайте алгоритм для сериализации и десериализации бинарного дерева. Нет ограничений на то, как ваш алгоритм сериализации/десериализации должен работать. Вам нужно просто гарантировать, что бинарное дерево может быть сериализовано в строку, и эта строка может быть десериализована в исходную структуру дерева.
Уточнение: формат ввода/вывода такой же, как в LeetCode для сериализации бинарного дерева. Вам не обязательно придерживаться этого формата, так что будьте креативны и придумайте свои подходы.
Пример:
Input: root = [1,2,3,null,null,4,5] Output: [1,2,3,null,null,4,5]👨💻 Алгоритм: 1⃣Сериализация дерева: Используйте рекурсивный обход дерева в порядке root -> left subtree -> right subtree. Для каждого узла добавляйте его значение в строку сериализации. Если узел пустой, добавляйте "None". 2⃣Пример: Начните с корня, узел 1, строка сериализации становится "1,". Переходите к левому поддереву с корнем 2, строка сериализации становится "1,2,". Для узла 2, посетите его левый узел 3 ("1,2,3,None,None,") и правый узел 4 ("1,2,3,None,None,4,None,None"). Возвращайтесь к корню 1 и посетите его правое поддерево, узел 5 ("1,2,3,None,None,4,None,None,5,None,None,"). 3⃣Десериализация строки: Разделите строку на список значений. Используйте рекурсивную функцию для создания узлов дерева, извлекая значения из списка и восстанавливая структуру дерева. Если значение "None", узел пустой. 😎 Решение:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Codec:
def rserialize(self, root, string):
if root is None:
string += "null,"
else:
string += str(root.val) + ","
string = self.rserialize(root.left, string)
string = self.rserialize(root.right, string)
return string
def serialize(self, root):
return self.rserialize(root, "")
def rdeserialize(self, data_list):
if data_list[0] == "null":
data_list.pop(0)
return None
root = TreeNode(int(data_list.pop(0)))
root.left = self.rdeserialize(data_list)
root.right = self.rdeserialize(data_list)
return root
def deserialize(self, data):
data_list = data.split(',')
return self.rdeserialize(data_list)
Ставь 👍 и забирай 📚 Базу знаний9 125
#medium
Задача: 433. Minimum Genetic Mutation
Генетическая строка может быть представлена строкой длиной 8 символов, содержащей символы 'A', 'C', 'G' и 'T'.
Предположим, нам нужно исследовать мутацию от генетической строки startGene до генетической строки endGene, где одна мутация определяется как изменение одного символа в генетической строке.
Например, "AACCGGTT" --> "AACCGGTA" является одной мутацией.
Также существует генетический банк bank, который содержит все допустимые генетические мутации. Генетическая строка должна быть в банке, чтобы считаться допустимой.
Даны две генетические строки startGene и endGene и генетический банк bank, верните минимальное количество мутаций, необходимых для мутации от startGene до endGene. Если такой мутации не существует, верните -1.
Обратите внимание, что начальная строка считается допустимой, поэтому она может не быть включена в банк.
Пример:
Input: startGene = "AACCGGTT", endGene = "AACCGGTA", bank = ["AACCGGTA"] Output: 1👨💻 Алгоритм: 1⃣Инициализируйте очередь и множество seen. Очередь будет использоваться для выполнения BFS, а множество seen будет использоваться для предотвращения повторного посещения одного и того же узла. Изначально в очередь и множество должен быть помещен startGene. 2⃣Выполняйте BFS. На каждом узле, если node == endGene, верните количество шагов, пройденных до этого момента. В противном случае, итеративно заменяйте каждый символ в строке на один из "A", "C", "G", "T" для нахождения соседей. Для каждого соседа, если он еще не был посещен и находится в bank, добавьте его в очередь и в множество seen. 3⃣Если BFS завершился и endGene не был найден, задача невыполнима. Верните -1. 😎 Решение:
from collections import deque
class Solution:
def minMutation(self, start: str, end: str, bank: List[str]) -> int:
queue = deque([start])
seen = set([start])
steps = 0
while queue:
for _ in range(len(queue)):
node = queue.popleft()
if node == end:
return steps
for c in "ACGT":
for i in range(len(node)):
neighbor = node[:i] + c + node[i+1:]
if neighbor not in seen and neighbor in bank:
queue.append(neighbor)
seen.add(neighbor)
steps += 1
return -1
Ставь 👍 и забирай 📚 Базу знаний9 125
#medium
Задача: 298. Binary Tree Longest Consecutive Sequence
Дан корень бинарного дерева, верните длину самого длинного пути последовательных значений.
Путь последовательных значений — это путь, где значения увеличиваются на единицу вдоль пути.
Обратите внимание, что путь может начинаться с любого узла в дереве, и вы не можете перейти от узла к его родителю на пути.
Пример:
Input: root = [1,null,3,2,4,null,null,null,5] Output: 3 Explanation: Longest consecutive sequence path is 3-4-5, so return 3.👨💻 Алгоритм: 1⃣Инициализация и начало обхода: Начните обход дерева с корневого узла. Инициализируйте переменную length, чтобы хранить текущую длину последовательного пути, и передавайте её вниз по дереву. 2⃣Сравнение текущего узла с родительским узлом: Для каждого узла сравните его значение со значением родительского узла. Если значение текущего узла на единицу больше значения родительского узла, увеличьте length. Если значение текущего узла не является последовательным (не больше на единицу), сбросьте length на 1. 3⃣Обход дерева: Рекурсивно обходите левое и правое поддерево, передавая обновлённое значение length. В каждом узле обновляйте максимальную длину последовательного пути, если текущая длина больше. 😎 Решение:
class Solution:
def __init__(self):
self.maxLength = 0
def longestConsecutive(self, root: Optional[TreeNode]) -> int:
self.dfs(root, None, 0)
return self.maxLength
def dfs(self, node: Optional[TreeNode], parent: Optional[TreeNode], length: int) -> None:
if not node:
return
if parent and node.val == parent.val + 1:
length += 1
else:
length = 1
self.maxLength = max(self.maxLength, length)
self.dfs(node.left, node, length)
self.dfs(node.right, node, length)
Ставь 👍 и забирай 📚 Базу знаний9 125
⚡️ IT-обучение теперь в Telegram!
В cвязи с недавнем замедлением Ютуба — лучшие обучающие каналы переехали в Telegram
Вот каналы для айтишников:
👩💻 Python: @Python
📱 GitHub: @GitHub
👩💻 Frontend: @Frontend
⚙️ Backend: @Backend
🤓 Общее айти: @portalToIT
👩💻 Java: @Java
👩💻 C#: @Csharp
👩💻 С/С++: @Cpp
🖥 Базы Данных & SQL: @SQL
👩💻 Golang: @Golang
👩💻 PHP: @PHP
👩💻 Моб. разработка: @MobDev
👩💻 Разработка игр: @GameDev
👩💻 DevOps: @DevOps
🖥 Data Science: @DataScience
🤔 Хакинг & ИБ: @InfoSec
🐞 Тестирование: @QA
📱 Маркетинг: @Marketing
🖥 Дизайн: @Design
➡️ Сохраняйте себе, чтобы не потерять
9 125
#medium
Задача: 299. Bulls and Cows
Вы играете в игру "Быки и коровы" со своим другом.
Вы записываете секретное число и просите своего друга угадать, что это за число. Когда ваш друг делает предположение, вы даете ему подсказку со следующей информацией:
Количество "быков", то есть цифры в предположении, которые находятся на правильной позиции.
Количество "коров", то есть цифры в предположении, которые есть в вашем секретном числе, но находятся на неправильной позиции. Конкретно, это не-бычьи цифры в предположении, которые можно переставить так, чтобы они стали быками.
Дано секретное число secret и предположение вашего друга guess, верните подсказку для предположения вашего друга.
Подсказка должна быть в формате "xAyB", где x — количество быков, а y — количество коров. Обратите внимание, что и secret, и guess могут содержать повторяющиеся цифры.
Пример:
Input: secret = "1807", guess = "7810" Output: "1A3B" Explanation: Bulls are connected with a '|' and cows are underlined: "1807" | "7810"👨💻 Алгоритм: 1⃣Инициализация счетчиков: Инициализируйте количество быков и коров значениями ноль. Создайте хеш-таблицу для хранения символов строки secret и их частот. 2⃣Обход строки guess: Для каждого символа ch в строке guess: Если ch присутствует в строке secret: Если текущий символ ch совпадает с символом на той же позиции в secret (ch == secret[idx]): Увеличьте количество быков: bulls += 1. Обновите количество коров, если количество текущего символа в хеш-таблице отрицательное или равно нулю (то есть этот символ уже использовался для коров): cows -= int(h[ch] <= 0). Если текущий символ ch не совпадает с символом на той же позиции в secret (ch != secret[idx]): Увеличьте количество коров, если количество текущего символа в хеш-таблице больше нуля: cows += int(h[ch] > 0). Обновите хеш-таблицу, помечая текущий символ как использованный: h[ch] -= 1. 3⃣Возврат результата: Верните количество быков и коров в формате "xAyB". 😎 Решение:
class Solution:
def getHint(self, secret: str, guess: str) -> str:
from collections import defaultdict
h = defaultdict(int)
for ch in secret:
h[ch] += 1
bulls = 0
cows = 0
n = len(guess)
secretArray = list(secret)
guessArray = list(guess)
for idx in range(n):
ch = guessArray[idx]
if ch in h:
if ch == secretArray[idx]:
bulls += 1
if h[ch] <= 0:
cows -= 1
else:
if h[ch] > 0:
cows += 1
h[ch] -= 1
return f"{bulls}A{cows}B"
Ставь 👍 и забирай 📚 Базу знаний9 125
#medium
Задача: 300. Longest Increasing Subsequence
Дан массив целых чисел nums, верните длину самой длинной строго возрастающей подпоследовательности.
Пример:
Input: nums = [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.👨💻 Алгоритм: 1⃣Инициализируйте массив dp длиной nums.length, все элементы которого равны 1. dp[i] представляет длину самой длинной возрастающей подпоследовательности, которая заканчивается элементом с индексом i. 2⃣Итерируйтесь от i = 1 до i = nums.length - 1. В каждой итерации используйте второй цикл for для итерации от j = 0 до j = i - 1 (все элементы перед i). Для каждого элемента перед i, проверьте, меньше ли этот элемент, чем nums[i]. Если да, установите dp[i] = max(dp[i], dp[j] + 1). 3⃣Верните максимальное значение из dp. 😎 Решение:
class Solution:
def lengthOfLIS(self, nums: list[int]) -> int:
if not nums:
return 0
dp = [1] * len(nums)
for i in range(1, len(nums)):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
Ставь 👍 и забирай 📚 Базу знаний9 125
+4
Senior-разработчик создал крутейший канал про SQL
Благодаря простым картинкам даже новичок научится разрабатывать приложения с использованием баз данных.
Присоединяйтесь: @SQL
9 125
#medium
Задача: 395. Longest Substring with At Least K Repeating Characters
Дана строка s и целое число k, верните длину самой длинной подстроки строки s, такая что частота каждого символа в этой подстроке больше или равна k.
Если такой подстроки не существует, верните 0.
Пример:
Input: s = "aaabb", k = 3 Output: 3 Explanation: The longest substring is "aaa", as 'a' is repeated 3 times.👨💻 Алгоритм: 1⃣Генерируйте подстроки из строки s, начиная с индекса start и заканчивая индексом end. Используйте массив countMap для хранения частоты каждого символа в подстроке. 2⃣Метод isValid использует countMap для проверки, что каждый символ в подстроке встречается как минимум k раз. Если условие выполняется, текущая подстрока считается допустимой. 3⃣Отслеживайте максимальную длину допустимой подстроки, обновляя её, когда найдена более длинная подстрока, удовлетворяющая условиям. В конце возвращайте длину самой длинной подстроки. 😎 Решение:
class Solution:
def longestSubstring(self, s: str, k: int) -> int:
if len(s) == 0 or k > len(s):
return 0
n = len(s)
result = 0
for start in range(n):
count_map = [0] * 26
for end in range(start, n):
count_map[ord(s[end]) - ord('a')] += 1
if self.is_valid(count_map, k):
result = max(result, end - start + 1)
return result
def is_valid(self, count_map, k):
count_letters = 0
count_at_least_k = 0
for count in count_map:
if count > 0:
count_letters += 1
if count >= k:
count_at_least_k += 1
return count_letters == count_at_least_k
Ставь 👍 и забирай 📚 Базу знаний9 125
🔥 Ресурсы для подготовки к работе в IT! 🔥
1️⃣ База собеседований IT – это уникальная коллекция собеседований от реальных топовых компаний: Сбер, Яндекс, ВТБ, Тинькофф, Озон, Wildberries и многие другие! 🏢 Мы собрали 150+ собеседований, чтобы ты мог подготовиться к интервью с уверенностью и успехом.
2️⃣ База тестовых заданий – твоё секретное оружие для успешного прохождения этапов отбора! 📋 Здесь ты найдёшь 121+ тестовых заданий от тех же топовых компаний: Сбер, Яндекс, ВТБ, Тинькофф, Озон, Wildberries. Решай реальные задачи и набирайся опыта для будущих собеседований!
🎯 Присоединяйся к базам и прокачай свои шансы на успешное трудоустройство!
9 125
#medium
Задача: 280. Wiggle Sort
Дан целочисленный массив nums, упорядочьте его так, чтобы nums[0] <= nums[1] >= nums[2] <= nums[3]....
Вы можете считать, что входной массив всегда имеет допустимый ответ.
Пример:
Input: nums = [3,5,2,1,6,4] Output: [3,5,1,6,2,4] Explanation: [1,6,2,5,3,4] is also accepted.👨💻 Алгоритм: 1⃣Итерируйтесь по каждому элементу с индексом i в массиве nums, начиная с 0 и до nums.length - 2, так как последний элемент не имеет следующего элемента для обмена. 2⃣Проверьте, является ли i четным и nums[i] > nums[i + 1]. Если это так, поменяйте местами nums[i] и nums[i + 1]. 3⃣Проверьте, является ли i нечетным и nums[i] < nums[i + 1]. Если это так, поменяйте местами nums[i] и nums[i + 1]. 😎 Решение:
class Solution:
def swap(self, nums, i, j):
nums[i], nums[j] = nums[j], nums[i]
def wiggleSort(self, nums):
for i in range(len(nums) - 1):
if (i % 2 == 0 and nums[i] > nums[i + 1]) or (i % 2 == 1 and nums[i] < nums[i + 1]):
self.swap(nums, i, i + 1)
Ставь 👍 и забирай 📚 Базу знаний9 125
CodHub теперь в Telegram!
Бесплатные обучающие материалы, которые лучше платных — книги, ресурсы, статьи и курсы топовых вузов страны тут:
👩💻 Материалы по Python
👩💻 Материалы по Frontend
👩💻 Материалы по Java
👩💻 Материалы по С#
👩💻 Материалы по C/C++
👩💻 Материалы по Хакингу
🖥 Материалы по SQL
👩💻 Материалы по Kotlin/Swift
👩💻 Материалы по Linux
🐞 Материалы по QA
👩💻 Материалы по Go
👩💻 Материалы по PHP
Подписываетесь: @CodHub_tg
