#medium
Задача: 362. Design Hit Counter
Дана матрица размером m x n, где каждая ячейка является либо стеной 'W', либо врагом 'E', либо пустой '0'. Верните максимальное количество врагов, которых можно уничтожить, используя одну бомбу. Вы можете разместить бомбу только в пустой ячейке.
Бомба уничтожает всех врагов в той же строке и столбце от точки установки до тех пор, пока не встретит стену, так как она слишком сильна, чтобы быть разрушенной.
Пример:
👨💻 Алгоритм:
1⃣ При вызове метода hit(int timestamp), добавьте временную метку в очередь.
2⃣ При вызове метода getHits(int timestamp), удалите все временные метки из очереди, которые старше 300 секунд от текущей временной метки.
3⃣ Верните размер очереди как количество попаданий за последние 5 минут.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 362. Design Hit Counter
Дана матрица размером m x n, где каждая ячейка является либо стеной 'W', либо врагом 'E', либо пустой '0'. Верните максимальное количество врагов, которых можно уничтожить, используя одну бомбу. Вы можете разместить бомбу только в пустой ячейке.
Бомба уничтожает всех врагов в той же строке и столбце от точки установки до тех пор, пока не встретит стену, так как она слишком сильна, чтобы быть разрушенной.
Пример:
Input
["HitCounter", "hit", "hit", "hit", "getHits", "hit", "getHits", "getHits"]
[[], [1], [2], [3], [4], [300], [300], [301]]
Output
[null, null, null, null, 3, null, 4, 3]
Explanation
HitCounter hitCounter = new HitCounter();
hitCounter.hit(1); // hit at timestamp 1.
hitCounter.hit(2); // hit at timestamp 2.
hitCounter.hit(3); // hit at timestamp 3.
hitCounter.getHits(4); // get hits at timestamp 4, return 3.
hitCounter.hit(300); // hit at timestamp 300.
hitCounter.getHits(300); // get hits at timestamp 300, return 4.
hitCounter.getHits(301); // get hits at timestamp 301, return 3.
from collections import deque
class HitCounter:
def __init__(self):
self.hits = deque()
def hit(self, timestamp: int) -> None:
self.hits.append(timestamp)
def getHits(self, timestamp: int) -> int:
while self.hits and timestamp - self.hits[0] >= 300:
self.hits.popleft()
return len(self.hits)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯2❤1👍1
#medium
Задача: 443. String Compression
Дан массив символов chars, сжать его, используя следующий алгоритм:
Начните с пустой строки s. Для каждой группы последовательных повторяющихся символов в chars:
Если длина группы равна 1, добавьте символ к строке s.
В противном случае добавьте символ, а за ним длину группы.
Сжатая строка s не должна возвращаться отдельно, а вместо этого должна быть сохранена в входном массиве символов chars. Обратите внимание, что длины групп, которые равны 10 или более, будут разделены на несколько символов в chars.
После того как вы закончите модификацию входного массива, верните новую длину массива.
Вы должны написать алгоритм, который использует только постоянное дополнительное пространство.
Пример:
👨💻 Алгоритм:
1⃣ Объявите переменные i – первый индекс текущей группы, и res – длина ответа (сжатой строки). Инициализируйте i = 0, res = 0.
2⃣ Пока i меньше длины chars: Найдите длину текущей группы последовательных повторяющихся символов groupLength. Добавьте chars[i] к ответу (chars[res++] = chars[i]). Если groupLength > 1, добавьте строковое представление groupLength к ответу и увеличьте res соответственно. Увеличьте i на groupLength и перейдите к следующей группе.
3⃣ Верните res.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 443. String Compression
Дан массив символов chars, сжать его, используя следующий алгоритм:
Начните с пустой строки s. Для каждой группы последовательных повторяющихся символов в chars:
Если длина группы равна 1, добавьте символ к строке s.
В противном случае добавьте символ, а за ним длину группы.
Сжатая строка s не должна возвращаться отдельно, а вместо этого должна быть сохранена в входном массиве символов chars. Обратите внимание, что длины групп, которые равны 10 или более, будут разделены на несколько символов в chars.
После того как вы закончите модификацию входного массива, верните новую длину массива.
Вы должны написать алгоритм, который использует только постоянное дополнительное пространство.
Пример:
Input: chars = ["a","a","b","b","c","c","c"]
Output: Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"]
Explanation: The groups are "aa", "bb", and "ccc". This compresses to "a2b2c3".
class Solution:
def compress(self, chars: List[str]) -> int:
i = 0
res = 0
while i < len(chars):
group_length = 1
while (i + group_length < len(chars) and chars[i + group_length] == chars[i]):
group_length += 1
chars[res] = chars[i]
res += 1
if group_length > 1:
str_repr = str(group_length)
chars[res:res+len(str_repr)] = list(str_repr)
res += len(str_repr)
i += group_length
return res
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Swipe right or swipe left
Что делать, если твои мэтчи в жизни не такие точные, как твой код?
Спокойно, 14 февраля в 19:00 по МСК мы разберём, как ML анализирует speed dating и предсказывает match.
📌 Мы возьмем реальные данные со speed dating.
📌 Обучим модель, которая скажет: match или swipe left.
📌 Разберём, какие признаки реально важны (спойлер: работа в IT — не прям гарантия успеха (наши маркетологи подтверждают 😥).
💡 Приходи, если хочешь прокачать свой Python, ML и, возможно, станешь идеальной парой, как самый стильные форсы.
👉 Записаться
Что делать, если твои мэтчи в жизни не такие точные, как твой код?
Спокойно, 14 февраля в 19:00 по МСК мы разберём, как ML анализирует speed dating и предсказывает match.
📌 Мы возьмем реальные данные со speed dating.
📌 Обучим модель, которая скажет: match или swipe left.
📌 Разберём, какие признаки реально важны (спойлер: работа в IT — не прям гарантия успеха (наши маркетологи подтверждают 😥).
💡 Приходи, если хочешь прокачать свой Python, ML и, возможно, станешь идеальной парой, как самый стильные форсы.
👉 Записаться
❤2
#hard
Задача: 363. Max Sum of Rectangle No Larger Than K
Дана матрица размером m x n и целое число k, вернуть максимальную сумму прямоугольника в матрице, такая что его сумма не превышает k.
Гарантируется, что будет прямоугольник с суммой, не превышающей k.
Пример:
👨💻 Алгоритм:
1⃣ Создать вспомогательную функцию updateResult, которая будет находить максимальную сумму подмассива в одномерном массиве, не превышающую k.
2⃣ Преобразовать каждую подматрицу в одномерный массив и применить к ней функцию updateResult.
3⃣ Вернуть максимальную найденную сумму.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 363. Max Sum of Rectangle No Larger Than K
Дана матрица размером m x n и целое число k, вернуть максимальную сумму прямоугольника в матрице, такая что его сумма не превышает k.
Гарантируется, что будет прямоугольник с суммой, не превышающей k.
Пример:
Input: matrix = [[1,0,1],[0,-2,3]], k = 2
Output: 2
Explanation: Because the sum of the blue rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).
class Solution:
def __init__(self):
self.result = float('-inf')
def updateResult(self, nums, k):
import bisect
sum_, prefix_sums = 0, [0]
for num in nums:
sum_ += num
idx = bisect.bisect_left(prefix_sums, sum_ - k)
if idx < len(prefix_sums):
self.result = max(self.result, sum_ - prefix_sums[idx])
bisect.insort(prefix_sums, sum_)
def maxSumSubmatrix(self, matrix, k):
rows, cols = len(matrix), len(matrix[0])
for i in range(rows):
row_sum = [0] * cols
for row in range(i, rows):
for col in range(cols):
row_sum[col] += matrix[row][col]
self.updateResult(row_sum, k)
if self.result == k:
return self.result
return self.result
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 445. Add Two Numbers II
Вам даны два непустых связанных списка, представляющих два неотрицательных целых числа. Самый значимый разряд стоит первым, и каждый из их узлов содержит одну цифру. Сложите два числа и верните сумму в виде связанного списка.
Вы можете предположить, что оба числа не содержат начальных нулей, за исключением самого числа 0.
Пример:
👨💻 Алгоритм:
1⃣ Создайте два связанных списка r1 и r2, чтобы хранить перевернутые связанные списки l1 и l2 соответственно. Создайте два целых числа totalSum и carry для хранения суммы и переноса текущих цифр. Создайте новый ListNode, ans, который будет хранить сумму текущих цифр. Мы будем складывать два числа, используя перевернутый список, добавляя цифры по одной. Продолжаем, пока не пройдем все узлы в r1 и r2.
2⃣ Если r1 не равен null, добавляем r1.val к totalSum. Если r2 не равен null, добавляем r2.val к totalSum. Устанавливаем ans.val = totalSum % 10. Сохраняем перенос как totalSum / 10. Создаем новый ListNode, newNode, который будет иметь значение как перенос. Устанавливаем next для newNode как ans. Обновляем ans = newNode, чтобы использовать ту же переменную ans для следующей итерации. Обновляем totalSum = carry.
3⃣ Если carry == 0, это означает, что newNode, созданный в финальной итерации цикла while, имеет значение 0. Поскольку мы выполняем ans = newNode в конце каждой итерации цикла while, чтобы избежать возврата связанного списка с головой, равной 0 (начальный ноль), возвращаем следующий элемент, т.е. возвращаем ans.next. В противном случае, если перенос не равен 0, значение ans не равно нулю. Следовательно, просто возвращаем ans.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 445. Add Two Numbers II
Вам даны два непустых связанных списка, представляющих два неотрицательных целых числа. Самый значимый разряд стоит первым, и каждый из их узлов содержит одну цифру. Сложите два числа и верните сумму в виде связанного списка.
Вы можете предположить, что оба числа не содержат начальных нулей, за исключением самого числа 0.
Пример:
Input: l1 = [7,2,4,3], l2 = [5,6,4]
Output: [7,8,0,7]
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
temp = None
while head:
temp = head.next
head.next = prev
prev = head
head = temp
return prev
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
r1 = self.reverseList(l1)
r2 = self.reverseList(l2)
total_sum = 0
carry = 0
ans = ListNode()
while r1 or r2:
if r1:
total_sum += r1.val
r1 = r1.next
if r2:
total_sum += r2.val
r2 = r2.next
ans.val = total_sum % 10
carry = total_sum // 10
head = ListNode(carry)
head.next = ans
ans = head
total_sum = carry
return ans.next if carry == 0 else ans
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
#hard
Задача: 446. Arithmetic Slices II - Subsequence
Дан целочисленный массив nums, вернуть количество всех арифметических подпоследовательностей nums.
Последовательность чисел называется арифметической, если она состоит как минимум из трех элементов и если разница между любыми двумя последовательными элементами одинаковая.
Например, [1, 3, 5, 7, 9], [7, 7, 7, 7] и [3, -1, -5, -9] являются арифметическими последовательностями.
Например, [1, 1, 2, 5, 7] не является арифметической последовательностью.
Подпоследовательность массива - это последовательность, которая может быть образована путем удаления некоторых элементов (возможно, ни одного) из массива.
Например, [2, 5, 10] является подпоследовательностью [1, 2, 1, 2, 4, 1, 5, 10].
Тестовые случаи сгенерированы таким образом, что ответ помещается в 32-битное целое число.
Пример:
👨💻 Алгоритм:
1⃣ Мы можем использовать поиск в глубину (DFS) для генерации всех подпоследовательностей.
2⃣ Мы можем проверить, является ли подпоследовательность арифметической, согласно ее определению.
3⃣ Возвращаем количество всех арифметических подпоследовательностей.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 446. Arithmetic Slices II - Subsequence
Дан целочисленный массив nums, вернуть количество всех арифметических подпоследовательностей nums.
Последовательность чисел называется арифметической, если она состоит как минимум из трех элементов и если разница между любыми двумя последовательными элементами одинаковая.
Например, [1, 3, 5, 7, 9], [7, 7, 7, 7] и [3, -1, -5, -9] являются арифметическими последовательностями.
Например, [1, 1, 2, 5, 7] не является арифметической последовательностью.
Подпоследовательность массива - это последовательность, которая может быть образована путем удаления некоторых элементов (возможно, ни одного) из массива.
Например, [2, 5, 10] является подпоследовательностью [1, 2, 1, 2, 4, 1, 5, 10].
Тестовые случаи сгенерированы таким образом, что ответ помещается в 32-битное целое число.
Пример:
Input: nums = [2,4,6,8,10]
Output: 7
Explanation: All arithmetic subsequence slices are:
[2,4,6]
[4,6,8]
[6,8,10]
[2,4,6,8]
[4,6,8,10]
[2,4,6,8,10]
[2,6,10]
class Solution:
def __init__(self):
self.n = 0
self.ans = 0
def dfs(self, dep, A, cur):
if dep == self.n:
if len(cur) < 3:
return
for i in range(1, len(cur)):
if cur[i] - cur[i - 1] != cur[1] - cur[0]:
return
self.ans += 1
return
self.dfs(dep + 1, A, cur)
cur.append(A[dep])
self.dfs(dep + 1, A, cur)
cur.pop()
def numberOfArithmeticSlices(self, A):
self.n = len(A)
self.ans = 0
self.dfs(0, A, [])
return self.ans
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 364. Nested List Weight Sum II
Вам дан вложенный список целых чисел nestedList. Каждый элемент является либо целым числом, либо списком, элементы которого также могут быть целыми числами или другими списками.
Глубина целого числа — это количество списков, внутри которых оно находится. Например, вложенный список [1,[2,2],[[3],2],1] имеет значение каждого целого числа, установленное равным его глубине. Пусть maxDepth будет максимальной глубиной любого целого числа.
Вес целого числа определяется как maxDepth - (глубина целого числа) + 1.
Верните сумму каждого целого числа в nestedList, умноженную на его вес.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать первый уровень BFS-дерева, добавив все элементы из входного nestedList в очередь.
2⃣ Для каждого уровня извлекать передний элемент из очереди. Если это список, то добавить его элементы в очередь. В противном случае обновить значения sumOfElements, maxDepth и sumOfProducts.
3⃣ Когда очередь станет пустой, вернуть значение (maxDepth + 1) * sumOfElements - sumOfProducts.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 364. Nested List Weight Sum II
Вам дан вложенный список целых чисел nestedList. Каждый элемент является либо целым числом, либо списком, элементы которого также могут быть целыми числами или другими списками.
Глубина целого числа — это количество списков, внутри которых оно находится. Например, вложенный список [1,[2,2],[[3],2],1] имеет значение каждого целого числа, установленное равным его глубине. Пусть maxDepth будет максимальной глубиной любого целого числа.
Вес целого числа определяется как maxDepth - (глубина целого числа) + 1.
Верните сумму каждого целого числа в nestedList, умноженную на его вес.
Пример:
Input: nestedList = [[1,1],2,[1,1]]
Output: 8
Explanation: Four 1's with a weight of 1, one 2 with a weight of 2.
1*1 + 1*1 + 2*2 + 1*1 + 1*1 = 8
from collections import deque
class Solution:
def depthSumInverse(self, nestedList):
queue = deque(nestedList)
depth = 1
maxDepth = 0
sumOfElements = 0
sumOfProducts = 0
while queue:
size = len(queue)
maxDepth = max(maxDepth, depth)
for _ in range(size):
nested = queue.popleft()
if nested.isInteger():
value = nested.getInteger()
sumOfElements += value
sumOfProducts += value * depth
else:
queue.extend(nested.getList())
depth += 1
return (maxDepth + 1) * sumOfElements - sumOfProducts
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
#medium
Задача: 366. Find Leaves of Binary Tree
Дан корень бинарного дерева, соберите узлы дерева следующим образом:
Соберите все листовые узлы.
Удалите все листовые узлы.
Повторяйте, пока дерево не станет пустым.
Пример:
👨💻 Алгоритм:
1⃣ Реализовать функцию getHeight(node), которая будет вычислять высоту каждого узла в дереве с использованием рекурсивного обхода в глубину (post-order). Если узел является null, вернуть -1.
2⃣ Сохранить пары (высота, значение) для всех узлов и отсортировать их по высоте.
3⃣ Организовать узлы по высоте и вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 366. Find Leaves of Binary Tree
Дан корень бинарного дерева, соберите узлы дерева следующим образом:
Соберите все листовые узлы.
Удалите все листовые узлы.
Повторяйте, пока дерево не станет пустым.
Пример:
Input: root = [1,2,3,4,5]
Output: [[4,5,3],[2],[1]]
Explanation:
[[3,5,4],[2],[1]] and [[3,4,5],[2],[1]] are also considered correct answers since per each level it does not matter the order on which elements are returned.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def __init__(self):
self.pairs = []
def getHeight(self, node):
if not node:
return -1
leftHeight = self.getHeight(node.left)
rightHeight = self.getHeight(node.right)
currHeight = max(leftHeight, rightHeight) + 1
self.pairs.append((currHeight, node.val))
return currHeight
def findLeaves(self, root):
self.getHeight(root)
self.pairs.sort()
solution = []
currentHeight = -1
for height, val in self.pairs:
if height != currentHeight:
solution.append([])
currentHeight = height
solution[-1].append(val)
return solution
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#hard
Задача: 591. Tag Validator
Дана строка, представляющая фрагмент кода, реализуйте валидатор тегов для разбора кода и определения его корректности.
Фрагмент кода считается корректным, если соблюдаются все следующие правила:
Код должен быть заключен в корректный закрытый тег. В противном случае код некорректен.
Закрытый тег (не обязательно корректный) имеет точно следующий формат: <TAG_NAME>TAG_CONTENT</TAG_NAME>. Среди них <TAG_NAME> — это начальный тег, а </TAG_NAME> — конечный тег. TAG_NAME в начальном и конечном тегах должен быть одинаковым. Закрытый тег корректен, если и только если TAG_NAME и TAG_CONTENT корректны.
Корректное TAG_NAME содержит только заглавные буквы и имеет длину в диапазоне [1, 9]. В противном случае TAG_NAME некорректен.
Корректное TAG_CONTENT может содержать другие корректные закрытые теги, cdata и любые символы (см. примечание 1), КРОМЕ неподходящих <, неподходящих начальных и конечных тегов, и неподходящих или закрытых тегов с некорректным TAG_NAME. В противном случае TAG_CONTENT некорректен.
Начальный тег неподходящий, если нет конечного тега с тем же TAG_NAME, и наоборот. Однако нужно также учитывать проблему несбалансированных тегов, когда они вложены.
< неподходящий, если не удается найти последующий >. И когда вы находите < или </, все последующие символы до следующего > должны быть разобраны как TAG_NAME (не обязательно корректный).
cdata имеет следующий формат: <![CDATA[CDATA_CONTENT]]>. Диапазон CDATA_CONTENT определяется как символы между <![CDATA[ и первым последующим ]]>.
CDATA_CONTENT может содержать любые символы. Функция cdata заключается в том, чтобы запретить валидатору разбирать CDATA_CONTENT, поэтому даже если в нем есть символы, которые могут быть разобраны как тег (корректный или некорректный), вы должны рассматривать их как обычные символы.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте стек для отслеживания открытых тегов и флаг для определения наличия тегов. Используйте регулярное выражение для проверки корректности TAG_NAME, TAG_CONTENT и CDATA.
2⃣ Пройдитесь по строке, проверяя каждый символ. Если встретите <, определите тип тега (начальный, конечный или CDATA). Обновите стек и индексы в зависимости от найденного типа.
3⃣ В конце проверьте, что стек пуст (все теги корректно закрыты) и верните результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 591. Tag Validator
Дана строка, представляющая фрагмент кода, реализуйте валидатор тегов для разбора кода и определения его корректности.
Фрагмент кода считается корректным, если соблюдаются все следующие правила:
Код должен быть заключен в корректный закрытый тег. В противном случае код некорректен.
Закрытый тег (не обязательно корректный) имеет точно следующий формат: <TAG_NAME>TAG_CONTENT</TAG_NAME>. Среди них <TAG_NAME> — это начальный тег, а </TAG_NAME> — конечный тег. TAG_NAME в начальном и конечном тегах должен быть одинаковым. Закрытый тег корректен, если и только если TAG_NAME и TAG_CONTENT корректны.
Корректное TAG_NAME содержит только заглавные буквы и имеет длину в диапазоне [1, 9]. В противном случае TAG_NAME некорректен.
Корректное TAG_CONTENT может содержать другие корректные закрытые теги, cdata и любые символы (см. примечание 1), КРОМЕ неподходящих <, неподходящих начальных и конечных тегов, и неподходящих или закрытых тегов с некорректным TAG_NAME. В противном случае TAG_CONTENT некорректен.
Начальный тег неподходящий, если нет конечного тега с тем же TAG_NAME, и наоборот. Однако нужно также учитывать проблему несбалансированных тегов, когда они вложены.
< неподходящий, если не удается найти последующий >. И когда вы находите < или </, все последующие символы до следующего > должны быть разобраны как TAG_NAME (не обязательно корректный).
cdata имеет следующий формат: <![CDATA[CDATA_CONTENT]]>. Диапазон CDATA_CONTENT определяется как символы между <![CDATA[ и первым последующим ]]>.
CDATA_CONTENT может содержать любые символы. Функция cdata заключается в том, чтобы запретить валидатору разбирать CDATA_CONTENT, поэтому даже если в нем есть символы, которые могут быть разобраны как тег (корректный или некорректный), вы должны рассматривать их как обычные символы.
Пример:
Input: code = "<DIV>This is the first line <![CDATA[<div>]]></DIV>"
Output: true
import re
class Solution:
def __init__(self):
self.stack = []
self.contains_tag = False
def is_valid_tag_name(self, s, ending):
if ending:
if self.stack and self.stack[-1] == s:
self.stack.pop()
else:
return False
else:
self.contains_tag = True
self.stack.append(s)
return True
def isValid(self, code: str) -> bool:
pattern = re.compile(r"<[A-Z]{0,9}>([^<]*(<((\/?[A-Z]{1,9}>)|(!\[CDATA\[.*?\]\]>)))?)*")
if not pattern.fullmatch(code):
return False
i = 0
while i < len(code):
ending = False
if not self.stack and self.contains_tag:
return False
if code[i] == '<':
if code[i + 1] == '!':
i = code.find("]]>", i + 1)
if i == -1:
return False
continue
if code[i + 1] == '/':
i += 1
ending = True
close_index = code.find('>', i + 1)
if close_index == -1 or not self.is_valid_tag_name(code[i + 1:close_index], ending):
return False
i = close_index
i += 1
return not self.stack
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#hard
Задача: 710. Random Pick with Blacklist
Вам дано целое число n и массив уникальных целых чисел blacklist. Разработайте алгоритм выбора случайного целого числа из диапазона [0, n - 1], не входящего в черный список. Любое целое число, находящееся в указанном диапазоне и не входящее в черный список, должно с равной вероятностью быть возвращено. Оптимизируйте алгоритм так, чтобы он минимизировал количество обращений к встроенной функции random вашего языка. Реализуйте класс Solution: Solution(int n, int[] blacklist) Инициализирует объект целым числом n и целым числом из черного списка blacklist. int pick() Возвращает случайное целое число в диапазоне [0, n - 1] и не входящее в черный список.
Пример:
👨💻 Алгоритм:
1⃣ Создайте маппинг для чисел, входящих в черный список, чтобы сопоставить их с числами из диапазона [n - len(blacklist), n - 1], которые не входят в черный список.
2⃣ Создайте массив для хранения возможных чисел для выбора, исключая числа из черного списка.
3⃣ При каждом вызове функции pick() используйте встроенную функцию random для выбора случайного индекса из массива возможных чисел и возвращайте соответствующее значение.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 710. Random Pick with Blacklist
Вам дано целое число n и массив уникальных целых чисел blacklist. Разработайте алгоритм выбора случайного целого числа из диапазона [0, n - 1], не входящего в черный список. Любое целое число, находящееся в указанном диапазоне и не входящее в черный список, должно с равной вероятностью быть возвращено. Оптимизируйте алгоритм так, чтобы он минимизировал количество обращений к встроенной функции random вашего языка. Реализуйте класс Solution: Solution(int n, int[] blacklist) Инициализирует объект целым числом n и целым числом из черного списка blacklist. int pick() Возвращает случайное целое число в диапазоне [0, n - 1] и не входящее в черный список.
Пример:
Input
["Solution", "pick", "pick", "pick", "pick", "pick", "pick", "pick"]
[[7, [2, 3, 5]], [], [], [], [], [], [], []]
Output
[null, 0, 4, 1, 6, 1, 0, 4]
import random
class Solution:
def __init__(self, n, blacklist):
self.mapping = {}
self.range_size = n - len(blacklist)
blacklist_set = set(blacklist)
last = n - 1
for b in blacklist:
if b < self.range_size:
while last in blacklist_set:
last -= 1
self.mapping[b] = last
last -= 1
def pick(self):
idx = random.randint(0, self.range_size - 1)
return self.mapping.get(idx, idx)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Forwarded from easyoffer
Привет, ребята!
1,5 года я учился на программиста, а сайт easyoffer.ru стал моим пет-проектом. Я создавал его, потому что:
а) нужно было добавить хоть какой-нибудь проект в резюме
б) подготовиться к прохождению собесов
И всё получилось! Благодаря еasyoffer я успешно прошёл собеседование и устроился Python Junior-разработчиком на удаленку с зарплатой 115 тысяч рублей.
Однако ещё во время разработки я понял, что у этого проекта есть потенциал. Казалось, что сайт может стать популярным и, возможно, превратиться в стартап.
По-этому я с самого начала заложил в проект минимальную бизнес-модель, на случай, если сайт начнёт набирать трафик. Я предложил пользователям полный доступ к сайту в обмен на подписку на Telegram-каналы. Это позволяло развивать аудиторию, а в будущем — зарабатывать на рекламе.
Результат превзошёл ожидания!
С момента запуска easyoffer посетило 400 тысяч человек. А когда доход с рекламы превысил мою зарплату программиста, я принял решение уйти с работы и полностью посвятить себя разработке новой версии сайта.
Вот так, зайдя в IT, через 4 месяца вышел через свой же пет-проект. Мне очень повезло
Уже год я работаю над easyoffer 2.0.
Это будет более масштабный и качественной новый проект:
– Появится тренажер
– Появятся задачи из собесов
– Фильтрация контента по грейдам
и еще очень много фич, о которых я расскажу позже.
Хочу, довести easyoffer до ума, чтобы сайт стал настоящим помощником для всех, кто готовится к собеседованиям.
По этому в ближайшее время я объявлю о старте краудфандинговой кампании, чтобы ускорить разработку и я готов щедро отблагодарить всех, кто поддержит проект.
А те, кто поддержат проект первыми, получат специальные лимитированные выгодные вознаграждения. Следите за этим телеграм каналом, если хотите стать первыми сапортерами.
1,5 года я учился на программиста, а сайт easyoffer.ru стал моим пет-проектом. Я создавал его, потому что:
а) нужно было добавить хоть какой-нибудь проект в резюме
б) подготовиться к прохождению собесов
И всё получилось! Благодаря еasyoffer я успешно прошёл собеседование и устроился Python Junior-разработчиком на удаленку с зарплатой 115 тысяч рублей.
Однако ещё во время разработки я понял, что у этого проекта есть потенциал. Казалось, что сайт может стать популярным и, возможно, превратиться в стартап.
По-этому я с самого начала заложил в проект минимальную бизнес-модель, на случай, если сайт начнёт набирать трафик. Я предложил пользователям полный доступ к сайту в обмен на подписку на Telegram-каналы. Это позволяло развивать аудиторию, а в будущем — зарабатывать на рекламе.
Результат превзошёл ожидания!
С момента запуска easyoffer посетило 400 тысяч человек. А когда доход с рекламы превысил мою зарплату программиста, я принял решение уйти с работы и полностью посвятить себя разработке новой версии сайта.
Вот так, зайдя в IT, через 4 месяца вышел через свой же пет-проект. Мне очень повезло
Уже год я работаю над easyoffer 2.0.
Это будет более масштабный и качественной новый проект:
– Появится тренажер
– Появятся задачи из собесов
– Фильтрация контента по грейдам
и еще очень много фич, о которых я расскажу позже.
Хочу, довести easyoffer до ума, чтобы сайт стал настоящим помощником для всех, кто готовится к собеседованиям.
По этому в ближайшее время я объявлю о старте краудфандинговой кампании, чтобы ускорить разработку и я готов щедро отблагодарить всех, кто поддержит проект.
А те, кто поддержат проект первыми, получат специальные лимитированные выгодные вознаграждения. Следите за этим телеграм каналом, если хотите стать первыми сапортерами.
❤1
#medium
Задача: 764. Largest Plus Sign
Вам дано целое число n. У вас есть бинарная сетка размером n x n, в которой все значения изначально равны 1, за исключением некоторых индексов, указанных в массиве mines. Элемент массива mines с индексом i определяется как mines[i] = [xi, yi], где grid[xi][yi] == 0.
Верните порядок самого большого крестообразного знака из 1, выровненного по осям, который содержится в сетке. Если такого знака нет, верните 0.
Крестообразный знак из 1 порядка k имеет некоторый центр grid[r][c] == 1, а также четыре луча длиной k - 1, идущих вверх, вниз, влево и вправо, состоящие из 1. Обратите внимание, что за пределами лучей креста могут быть 0 или 1, проверяется только соответствующая область крестообразного знака на наличие 1.
Пример:
👨💻 Алгоритм:
1⃣ Создайте сетку размером n x n, заполненную единицами. Затем используйте массив mines, чтобы установить значения нулей в соответствующих ячейках сетки.
2⃣ Для каждой ячейки в сетке создайте четыре дополнительных сетки: left, right, up и down, которые будут хранить длину непрерывных единиц, простирающихся в соответствующем направлении от каждой ячейки.
3⃣ Пройдите по всей сетке и для каждой ячейки определите минимальную длину луча среди четырех направлений. Эта минимальная длина будет определять порядок крестообразного знака с центром в данной ячейке. Обновите максимальный порядок крестообразного знака и верните его после завершения обхода всей сетки. Если такого знака нет, верните 0.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 764. Largest Plus Sign
Вам дано целое число n. У вас есть бинарная сетка размером n x n, в которой все значения изначально равны 1, за исключением некоторых индексов, указанных в массиве mines. Элемент массива mines с индексом i определяется как mines[i] = [xi, yi], где grid[xi][yi] == 0.
Верните порядок самого большого крестообразного знака из 1, выровненного по осям, который содержится в сетке. Если такого знака нет, верните 0.
Крестообразный знак из 1 порядка k имеет некоторый центр grid[r][c] == 1, а также четыре луча длиной k - 1, идущих вверх, вниз, влево и вправо, состоящие из 1. Обратите внимание, что за пределами лучей креста могут быть 0 или 1, проверяется только соответствующая область крестообразного знака на наличие 1.
Пример:
Input: n = 5, mines = [[4,2]]
Output: 2
Explanation: In the above grid, the largest plus sign can only be of order 2. One of them is shown.
class Solution:
def orderOfLargestPlusSign(self, N: int, mines: List[List[int]]) -> int:
banned = set()
for mine in mines:
banned.add(mine[0] * N + mine[1])
ans = 0
for r in range(N):
for c in range(N):
k = 0
while k <= r and r < N - k and k <= c and c < N - k and \
(r - k) * N + c not in banned and \
(r + k) * N + c not in banned and \
r * N + c - k not in banned and \
r * N + c + k not in banned:
k += 1
ans = max(ans, k)
return ans
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2
#hard
Задача: 711. Number of Distinct Islands II
Вам дана двоичная матричная сетка m x n. Остров - это группа 1 (представляющая сушу), соединенных в четырех направлениях (горизонтальном или вертикальном). Можно предположить, что все четыре края сетки окружены водой. Остров считается одинаковым с другим, если они имеют одинаковую форму, или имеют одинаковую форму после поворота (только на 90, 180 или 270 градусов) или отражения (влево/вправо или вверх/вниз). Верните количество разных островов.
Пример:
👨💻 Алгоритм:
1⃣ Пройдите по каждому элементу матрицы, если найдена земля (1), выполните DFS для обнаружения всех связанных с этим островом земель и сохраните форму острова.
2⃣ Нормализуйте форму острова, применив все возможные повороты и отражения, чтобы найти каноническую форму.
3⃣ Используйте множество для хранения всех уникальных канонических форм и верните размер этого множества.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 711. Number of Distinct Islands II
Вам дана двоичная матричная сетка m x n. Остров - это группа 1 (представляющая сушу), соединенных в четырех направлениях (горизонтальном или вертикальном). Можно предположить, что все четыре края сетки окружены водой. Остров считается одинаковым с другим, если они имеют одинаковую форму, или имеют одинаковую форму после поворота (только на 90, 180 или 270 градусов) или отражения (влево/вправо или вверх/вниз). Верните количество разных островов.
Пример:
Input: grid = [[1,1,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,1,1]]
Output: 1
def numDistinctIslands2(grid):
def dfs(i, j):
shape = []
stack = [(i, j)]
while stack:
x, y = stack.pop()
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] == 1:
grid[x][y] = 0
shape.append((x - i, y - j))
stack.extend([(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)])
return shape
def normalize(shape):
shapes = [[] for _ in range(8)]
for x, y in shape:
shapes[0].append((x, y))
shapes[1].append((x, -y))
shapes[2].append((-x, y))
shapes[3].append((-x, -y))
shapes[4].append((y, x))
shapes[5].append((y, -x))
shapes[6].append((-y, x))
shapes[7].append((-y, -x))
for s in shapes:
s.sort()
return min(shapes)
unique_islands = set()
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1:
shape = dfs(i, j)
unique_islands.add(tuple(normalize(shape)))
return len(unique_islands)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
#hard
Задача: 765. Couples Holding Hands
Есть n пар, сидящих на 2n местах, расположенных в ряд, и они хотят держаться за руки.
Люди и места представлены массивом целых чисел row, где row[i] — это ID человека, сидящего на i-м месте. Пары пронумерованы по порядку: первая пара — (0, 1), вторая пара — (2, 3) и так далее, до последней пары — (2n - 2, 2n - 1).
Верните минимальное количество перестановок, чтобы каждая пара сидела рядом. Перестановка состоит из выбора любых двух человек, которые встают и меняются местами.
Пример:
👨💻 Алгоритм:
1⃣ Мы могли бы предположить без доказательства, что решение, при котором мы делаем людей на каждом диване счастливыми по порядку, является оптимальным. Это предположение сильнее, чем гипотеза о жадном подходе, но кажется разумным, поскольку при каждом ходе мы делаем хотя бы одну пару счастливой.
2⃣ При таком предположении, для какого-то дивана с несчастливыми людьми X и Y, мы либо заменяем Y на партнера X, либо заменяем X на партнера Y. Для каждой из двух возможностей мы можем попробовать оба варианта, используя подход с возвратом.
3⃣ Для каждого дивана с двумя возможностями (т.е. оба человека на диване несчастливы) мы попробуем первый вариант, найдем ответ как ans1, затем отменим наш ход и попробуем второй вариант, найдем связанный ответ как ans2, отменим наш ход и затем вернем наименьший ответ.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 765. Couples Holding Hands
Есть n пар, сидящих на 2n местах, расположенных в ряд, и они хотят держаться за руки.
Люди и места представлены массивом целых чисел row, где row[i] — это ID человека, сидящего на i-м месте. Пары пронумерованы по порядку: первая пара — (0, 1), вторая пара — (2, 3) и так далее, до последней пары — (2n - 2, 2n - 1).
Верните минимальное количество перестановок, чтобы каждая пара сидела рядом. Перестановка состоит из выбора любых двух человек, которые встают и меняются местами.
Пример:
Input: row = [0,2,1,3]
Output: 1
Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
class Solution:
def minSwapsCouples(self, row: List[int]) -> int:
self.N = len(row) // 2
self.pairs = [[0, 0] for _ in range(self.N)]
for i in range(self.N):
self.pairs[i][0] = row[2 * i] // 2
self.pairs[i][1] = row[2 * i + 1] // 2
return self.solve(0)
def swap(self, a: int, b: int, c: int, d: int):
self.pairs[a][b], self.pairs[c][d] = self.pairs[c][d], self.pairs[a][b]
def solve(self, i: int) -> int:
if i == self.N:
return 0
x, y = self.pairs[i]
if x == y:
return self.solve(i + 1)
jx, kx, jy, ky = 0, 0, 0, 0
for j in range(i + 1, self.N):
for k in range(2):
if self.pairs[j][k] == x:
jx, kx = j, k
if self.pairs[j][k] == y:
jy, ky = j, k
self.swap(i, 1, jx, kx)
ans1 = 1 + self.solve(i + 1)
self.swap(i, 1, jx, kx)
self.swap(i, 0, jy, ky)
ans2 = 1 + self.solve(i + 1)
self.swap(i, 0, jy, ky)
return min(ans1, ans2)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
#easy
Задача: 766. Toeplitz Matrix
Дана матрица размером m x n. Вернуть true, если матрица является Тёплицевой. В противном случае вернуть false.
Матрица является Тёплицевой, если все диагонали, идущие от верхнего левого к нижнему правому углу, содержат одинаковые элементы.
Пример:
👨💻 Алгоритм:
1⃣ Что отличает две координаты (r1, c1) и (r2, c2) на одной диагонали? Оказывается, две координаты находятся на одной диагонали тогда и только тогда, когда r1 - c1 == r2 - c2.м
2⃣ Это приводит к следующей идее: запоминайте значение этой диагонали как groups[r - c]. Если обнаружено несоответствие, то матрица не является Тёплицевой; в противном случае, она является таковой.
3⃣ Таким образом, для каждой ячейки матрицы сохраняйте значение диагонали в словаре groups с ключом r - c. Проходите по всем ячейкам матрицы и проверяйте, совпадает ли текущее значение с сохранённым в groups. Если где-то обнаруживается несоответствие, верните false. Если все элементы соответствуют, верните true.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 766. Toeplitz Matrix
Дана матрица размером m x n. Вернуть true, если матрица является Тёплицевой. В противном случае вернуть false.
Матрица является Тёплицевой, если все диагонали, идущие от верхнего левого к нижнему правому углу, содержат одинаковые элементы.
Пример:
Input: matrix = [[1,2,3,4],[5,1,2,3],[9,5,1,2]]
Output: true
Explanation:
In the above grid, the diagonals are:
"[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]".
In each diagonal all elements are the same, so the answer is True.
class Solution:
def isToeplitzMatrix(self, matrix: List[List[int]]) -> bool:
groups = {}
for r in range(len(matrix)):
for c in range(len(matrix[0])):
if (r - c) not in groups:
groups[r - c] = matrix[r][c]
elif groups[r - c] != matrix[r][c]:
return False
return True
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Forwarded from easyoffer
Ищу работу пол года
Практически под каждым постом в этом канале я вижу комментарии от людей, которые ищут работу по полгода. Это перерастает в обсуждение того, как нужно (или не нужно) искать работу, почему процесс найма сломан и как они откликались на фейковые вакансии.
Честно говоря, искать работу полгода — это нонсенс. Очевидно, что человек делает что-то не так. Главная ошибка, которую совершают многие, — это создание иллюзии поиска работы.
То есть человек вроде бы ищет работу, но делает это неэффективно, тратя время на нецелевые действия. Например:
➖ Просматривает вакансии перед откликом.
➖ Пытается понять, подходит ли он под вакансию. Если считает, что не подходит — не откликается.
➖ Пишет сопроводительные письма (иногда даже уникальные под каждую вакансию).
➖ Заполняет анкеты, проходит тесты.
Все эти действия отнимают время, но не приводят к результату.
Почему это не работает?
HR-менеджер не может вручную отсмотреть 2000 откликов, оценить каждое резюме и прочитать сопроводительные письма. Поэтому компании используют ATS-системы (системы автоматического подбора), которые анализируют резюме и определяют процент его соответствия вакансии.
Что делать, чтобы повысить шансы?
1️⃣ Добавить ключевые навыки в резюме — и в основной текст, и в теги. Возьмите их с easyoffer.ru
2️⃣ Убрать нерелевантный опыт, оставить только подходящий.
3️⃣ Оформить опыт так, чтобы он выглядел релевантным. Если у вас его нет, укажите проекты, стажировки или другой опыт, который можно представить как работу от 1 года. Если опыт слишком большой, сузьте его до 6 лет.
4️⃣ Откликаться на все вакансии без разбору. Если вы Junior, не ищите только стажер или Junior-вакансии — пробуйте везде. Не отказывайте себе сами, пусть это решит HR
5️⃣ Сделать резюме публичным, потому что HR-менеджеры часто ищут кандидатов не только среди откликов, но и в базе резюме.
6️⃣ Используйте ИИ по минимуму – ATS-системы считывают это и помечают "сгенерировано ИИ"
‼️ Главное правило: чем больше откликов — тем выше шанс получить оффер. Делайте резюме удобным для ATS-систем, и вас заметят.
1. Посмотрите видео о том как я вывел свою резюме в Топ1 на HH
2. Посмотрите видео как я нашел первую работу
3. Прочитайте этот кейс про оптимизацию резюме
Если прям вообще тяжело.
Создайте несколько разных резюме. Создайте 2, 3 да хоть 10 резюме. Настройте авто-отлики и ждите приглашения на собесы.
Не нужно создавать иллюзию поиска работы, сделайте несколько простых и актуальных действий.
Практически под каждым постом в этом канале я вижу комментарии от людей, которые ищут работу по полгода. Это перерастает в обсуждение того, как нужно (или не нужно) искать работу, почему процесс найма сломан и как они откликались на фейковые вакансии.
Честно говоря, искать работу полгода — это нонсенс. Очевидно, что человек делает что-то не так. Главная ошибка, которую совершают многие, — это создание иллюзии поиска работы.
То есть человек вроде бы ищет работу, но делает это неэффективно, тратя время на нецелевые действия. Например:
Все эти действия отнимают время, но не приводят к результату.
Почему это не работает?
HR-менеджер не может вручную отсмотреть 2000 откликов, оценить каждое резюме и прочитать сопроводительные письма. Поэтому компании используют ATS-системы (системы автоматического подбора), которые анализируют резюме и определяют процент его соответствия вакансии.
Что делать, чтобы повысить шансы?
1️⃣ Добавить ключевые навыки в резюме — и в основной текст, и в теги. Возьмите их с easyoffer.ru
2️⃣ Убрать нерелевантный опыт, оставить только подходящий.
3️⃣ Оформить опыт так, чтобы он выглядел релевантным. Если у вас его нет, укажите проекты, стажировки или другой опыт, который можно представить как работу от 1 года. Если опыт слишком большой, сузьте его до 6 лет.
4️⃣ Откликаться на все вакансии без разбору. Если вы Junior, не ищите только стажер или Junior-вакансии — пробуйте везде. Не отказывайте себе сами, пусть это решит HR
5️⃣ Сделать резюме публичным, потому что HR-менеджеры часто ищут кандидатов не только среди откликов, но и в базе резюме.
6️⃣ Используйте ИИ по минимуму – ATS-системы считывают это и помечают "сгенерировано ИИ"
‼️ Главное правило: чем больше откликов — тем выше шанс получить оффер. Делайте резюме удобным для ATS-систем, и вас заметят.
1. Посмотрите видео о том как я вывел свою резюме в Топ1 на HH
2. Посмотрите видео как я нашел первую работу
3. Прочитайте этот кейс про оптимизацию резюме
Если прям вообще тяжело.
Создайте несколько разных резюме. Создайте 2, 3 да хоть 10 резюме. Настройте авто-отлики и ждите приглашения на собесы.
Не нужно создавать иллюзию поиска работы, сделайте несколько простых и актуальных действий.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1🤔1
#medium
Задача: 712. Minimum ASCII Delete Sum for Two Strings
Если даны две строки s1 и s2, верните наименьшую ASCII-сумму удаленных символов, чтобы сделать две строки равными.
Пример:
👨💻 Алгоритм:
1⃣ Создайте двумерный массив dp размером (len(s1) + 1) x (len(s2) + 1), где dp[i][j] будет хранить наименьшую ASCII-сумму удаленных символов для первых i символов s1 и первых j символов s2.
2⃣ Заполните первую строку и первый столбец массива dp суммами ASCII значений символов, которые необходимо удалить для достижения пустой строки.
3⃣ Заполните оставшуюся часть массива dp следующим образом: Если символы s1[i-1] и s2[j-1] равны, dp[i][j] = dp[i-1][j-1]. Иначе, dp[i][j] = min(dp[i-1][j] + ord(s1[i-1]), dp[i][j-1] + ord(s2[j-1])).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 712. Minimum ASCII Delete Sum for Two Strings
Если даны две строки s1 и s2, верните наименьшую ASCII-сумму удаленных символов, чтобы сделать две строки равными.
Пример:
Input: s1 = "sea", s2 = "eat"
Output: 231
def minimumDeleteSum(s1, s2):
dp = [[0] * (len(s2) + 1) for _ in range(len(s1) + 1)]
for i in range(1, len(s1) + 1):
dp[i][0] = dp[i - 1][0] + ord(s1[i - 1])
for j in range(1, len(s2) + 1):
dp[0][j] = dp[0][j - 1] + ord(s2[j - 1])
for i in range(1, len(s1) + 1):
for j in range(1, len(s2) + 1):
if s1[i - 1] == s2[j - 1]:
dp[i][j] = dp[i - 1][j - 1]
else:
dp[i][j] = min(dp[i - 1][j] + ord(s1[i - 1]), dp[i][j - 1] + ord(s2[j - 1]))
return dp[-1][-1]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 767. Reorganize String
Дана строка s, переставьте символы строки s так, чтобы любые два соседних символа не были одинаковыми.
Верните любую возможную перестановку строки s или верните "", если это невозможно.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте пустой список ans для хранения переставленных символов. Создайте приоритетную очередь pq, используя структуру данных кучи. Каждый элемент в pq — это кортеж, содержащий количество символов и сам символ. Приоритетная очередь упорядочена так, что элементы с большим количеством имеют более высокий приоритет.
2⃣ Извлеките элемент с наивысшим приоритетом из pq. Присвойте его количество и символ переменным count_first и char_first соответственно. Если ans пуст или текущий символ char_first отличается от последнего символа в ans, добавьте char_first в ans. Если количество char_first не равно нулю, уменьшите его на один. Если обновленное количество больше нуля, поместите его обратно в pq. Перейдите к следующей итерации.
3⃣ В противном случае, если char_first совпадает с последним символом в ans, нужно выбрать другой символ. Если pq пуста, верните пустую строку, так как переставить символы невозможно. Извлеките следующий элемент из pq, присвоив его количество и символ переменным count_second и char_second соответственно. Добавьте char_second в ans. Если количество char_second не равно нулю, уменьшите его на один. Если обновленное количество больше нуля, поместите его обратно в pq. Наконец, поместите оригинальный char_first обратно в pq. Верните переставленные символы как строку, объединив элементы в ans.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 767. Reorganize String
Дана строка s, переставьте символы строки s так, чтобы любые два соседних символа не были одинаковыми.
Верните любую возможную перестановку строки s или верните "", если это невозможно.
Пример:
Input: s = "aab"
Output: "aba"
import heapq
class Solution:
def reorganizeString(self, s: str) -> str:
charCounts = [0] * 26
for c in s:
charCounts[ord(c) - ord('a')] += 1
pq = []
for i in range(26):
if charCounts[i] > 0:
heapq.heappush(pq, (-charCounts[i], chr(i + ord('a'))))
result = []
while pq:
first = heapq.heappop(pq)
if not result or first[1] != result[-1]:
result.append(first[1])
if -first[0] > 1:
heapq.heappush(pq, (first[0] + 1, first[1]))
else:
if not pq:
return ""
second = heapq.heappop(pq)
result.append(second[1])
if -second[0] > 1:
heapq.heappush(pq, (second[0] + 1, second[1]))
heapq.heappush(pq, first)
return "".join(result)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
#medium
Задача: 713. Subarray Product Less Than K
Если задан массив целых чисел nums и целое число k, верните количество смежных подмассивов, в которых произведение всех элементов в подмассиве строго меньше k.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменные для отслеживания текущего произведения и количества допустимых подмассивов. Используйте два указателя для границ подмассива.
2⃣ Перемещайте правый указатель по массиву и умножайте текущий элемент на текущее произведение. Если произведение становится больше или равно k, перемещайте левый указатель, уменьшая произведение до тех пор, пока оно снова не станет меньше k.
3⃣ Подсчитайте количество подмассивов с текущим правым указателем, добавив к общему количеству допустимых подмассивов разницу между правым и левым указателями.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 713. Subarray Product Less Than K
Если задан массив целых чисел nums и целое число k, верните количество смежных подмассивов, в которых произведение всех элементов в подмассиве строго меньше k.
Пример:
Input: nums = [10,5,2,6], k = 100
Output: 8
def numSubarrayProductLessThanK(nums, k):
if k <= 1:
return 0
product = 1
count = 0
left = 0
for right in range(len(nums)):
product *= nums[right]
while product >= k:
product //= nums[left]
left += 1
count += right - left + 1
return count
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 714. Best Time to Buy and Sell Stock with Transaction Fee
Вам дан массив prices, где prices[i] - это цена данной акции в i-й день, и целое число fee, представляющее собой комиссию за сделку. Найдите максимальную прибыль, которую вы можете получить. Вы можете совершить сколько угодно сделок, но за каждую сделку вам придется заплатить комиссию. Примечание: Вы не можете совершать несколько сделок одновременно (то есть вы должны продать акции, прежде чем купить их снова). Комиссия за сделку взимается только один раз за каждую покупку и продажу акций.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте две переменные: cash, представляющую максимальную прибыль без наличия акций, и hold, представляющую максимальную прибыль с наличием акций.
2⃣ Пройдите по каждому элементу массива prices и обновите значения cash и hold, используя текущую цену и комиссию.
3⃣ Верните значение cash, которое будет максимальной прибылью без наличия акций.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 714. Best Time to Buy and Sell Stock with Transaction Fee
Вам дан массив prices, где prices[i] - это цена данной акции в i-й день, и целое число fee, представляющее собой комиссию за сделку. Найдите максимальную прибыль, которую вы можете получить. Вы можете совершить сколько угодно сделок, но за каждую сделку вам придется заплатить комиссию. Примечание: Вы не можете совершать несколько сделок одновременно (то есть вы должны продать акции, прежде чем купить их снова). Комиссия за сделку взимается только один раз за каждую покупку и продажу акций.
Пример:
Input: prices = [1,3,2,8,4,9], fee = 2
Output: 8
def maxProfit(prices, fee):
cash, hold = 0, -prices[0]
for price in prices:
cash = max(cash, hold + price - fee)
hold = max(hold, cash - price)
return cash
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
#medium
Задача: 771. Jewels and Stones
Вам даны строки jewels, представляющие типы камней, которые являются драгоценностями, и stones, представляющие камни, которые у вас есть. Каждый символ в stones является типом камня, который у вас есть. Вы хотите узнать, сколько из камней, которые у вас есть, также являются драгоценностями.
Буквы чувствительны к регистру, поэтому "a" считается другим типом камня, чем "A".
Пример:
👨💻 Алгоритм:
1⃣ Создайте множество из строки jewels для быстрой проверки, является ли камень драгоценностью. Это позволит эффективно проверять принадлежность каждого камня к драгоценностям.
2⃣ Инициализируйте счетчик для подсчета количества камней, которые являются драгоценностями. Пройдите по каждому символу в строке stones и проверьте, содержится ли этот символ в множестве jewels.
3⃣ Если символ содержится в множестве, увеличьте счетчик. В конце верните значение счетчика, которое будет количеством камней, являющихся драгоценностями.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 771. Jewels and Stones
Вам даны строки jewels, представляющие типы камней, которые являются драгоценностями, и stones, представляющие камни, которые у вас есть. Каждый символ в stones является типом камня, который у вас есть. Вы хотите узнать, сколько из камней, которые у вас есть, также являются драгоценностями.
Буквы чувствительны к регистру, поэтому "a" считается другим типом камня, чем "A".
Пример:
Input: jewels = "aA", stones = "aAAbbbb"
Output: 3
class Solution:
def numJewelsInStones(self, J: str, S: str) -> int:
ans = 0
for s in S:
for j in J:
if j == s:
ans += 1
break
return ans
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2