uz
Feedback
Python | LeetCode

Python | LeetCode

Kanalga Telegram’da o‘tish

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv

Ko'proq ko'rsatish
9 165
Obunachilar
-624 soatlar
-197 kunlar
-7230 kunlar
Postlar arxiv
Ищете стабильную видеосвязь и мессенджер? ⚡WhatsApp и Telegram работают с перебоями, Skype с октября без техподдержки — публи
Ищете стабильную видеосвязь и мессенджер? ⚡WhatsApp и Telegram работают с перебоями, Skype с октября без техподдержки — публичные мессенджеры не подходят для бизнеса. ✅Российская платформа МТС Линк доступна 99,9% времени. Попробуйте и убедитесь сами. Попробовать #реклама 16+ mts-link.ru О рекламодателе

Задача: 971. Flip Binary Tree To Match Preorder Traversal Сложность: medium Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order. Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект: Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage. Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1]. Пример:
Input: root = [1,2], voyage = [2,1]
Output: [-1]
Explanation: It is impossible to flip the nodes such that the pre-order traversal matches voyage.
👨‍💻 Алгоритм: 1⃣Выполните поиск в глубину. Если в каком-либо узле значение узла не соответствует значению в voyage, верните [-1]. 2⃣Иначе определите, когда нужно перевернуть: если следующее ожидаемое число в voyage (voyage[i]) отличается от следующего потомка. 3⃣Переверните узел, добавьте его значение в список перевернутых узлов и продолжите обход дерева, пока весь порядок обхода pre-order не будет соответствовать voyage. 😎 Решение:
class Solution:
    def flipMatchVoyage(self, root: TreeNode, voyage: List[int]) -> List[int]:
        self.flipped = []
        self.index = 0
        self.voyage = voyage

        self.dfs(root)
        if self.flipped and self.flipped[0] == -1:
            return [-1]
        return self.flipped

    def dfs(self, node):
        if node:
            if node.val != self.voyage[self.index]:
                self.flipped = [-1]
                return
            self.index += 1

            if self.index < len(self.voyage) and node.left and node.left.val != self.voyage[self.index]:
                self.flipped.append(node.val)
                self.dfs(node.right)
                self.dfs(node.left)
            else:
                self.dfs(node.left)
                self.dfs(node.right)
Ставь 👍 и забирай 📚 Базу знаний

Задача: 835. Image Overlap Сложность: medium Вам даны два изображения, img1 и img2, представленные как бинарные квадратные матрицы размером n x n. Бинарная матрица содержит только 0 и 1 в качестве значений. Мы можем сдвигать одно изображение как угодно, перемещая все биты 1 влево, вправо, вверх и/или вниз на любое количество единиц. Затем мы помещаем его поверх другого изображения. После этого мы можем вычислить перекрытие, подсчитав количество позиций, на которых в обоих изображениях есть 1. Также обратите внимание, что при сдвиге не допускается никакое вращение. Любые биты 1, которые перемещаются за пределы границ матрицы, стираются. Верните максимальное возможное перекрытие. Пример:
Input: img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]
Output: 3
Explanation: We translate img1 to right by 1 unit and down by 1 unit.
👨‍💻 Алгоритм: 1⃣Определите функцию shiftAndCount(xShift, yShift, M, R), которая смещает матрицу M относительно матрицы R на координаты (xShift, yShift) и подсчитывает количество единиц в зоне перекрытия. 2⃣Организуйте цикл по всем возможным комбинациям координат смещения (xShift, yShift). 3⃣На каждой итерации вызывайте функцию shiftAndCount() дважды для обоих направлений смещения и обновляйте максимальное количество перекрытий. 😎 Решение:
class Solution:
    def shiftAndCount(self, xShift, yShift, M, R):
        leftShiftCount = 0
        rightShiftCount = 0
        rRow = 0
        for mRow in range(yShift, len(M)):
            rCol = 0
            for mCol in range(xShift, len(M)):
                if M[mRow][mCol] == 1 and M[mRow][mCol] == R[rRow][rCol]:
                    leftShiftCount += 1
                if M[mRow][rCol] == 1 and M[mRow][rCol] == R[rRow][mCol]:
                    rightShiftCount += 1
                rCol += 1
            rRow += 1
        return max(leftShiftCount, rightShiftCount)

    def largestOverlap(self, A: List[List[int]], B: List[List[int]]) -> int:
        maxOverlaps = 0
        for yShift in range(len(A)):
            for xShift in range(len(A)):
                maxOverlaps = max(maxOverlaps, self.shiftAndCount(xShift, yShift, A, B))
                maxOverlaps = m
Ставь 👍 и забирай 📚 Базу знаний

Задача: 751. IP to CIDR Сложность: medium Дан указатель на начало односвязного списка и два целых числа left и right, где left <= right. Необходимо перевернуть узлы списка, начиная с позиции left и заканчивая позицией right, и вернуть измененный список. Пример:
Input: ip = "255.0.0.7", n = 10
Output: ["255.0.0.7/32","255.0.0.8/29","255.0.0.16/32"]
👨‍💻 Алгоритм: 1⃣Преобразовать начальный IP-адрес в целое число. 2⃣Пока количество оставшихся IP-адресов n больше нуля: Определить наибольший блок, который начинается с текущего IP-адреса и не превышает количество оставшихся IP-адресов. Добавить этот блок к результату. Увеличить текущий IP-адрес на размер блока. Уменьшить количество оставшихся IP-адресов n. 3⃣Преобразовать блоки обратно в формат CIDR и вернуть их. 😎 Решение:
def ip_to_int(ip):
    parts = ip.split('.')
    return (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])

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

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

def find_cidr_blocks(start_ip, n):
    start = ip_to_int(start_ip)
    result = []
    
    while n > 0:
        max_size = 1
        while max_size <= start and max_size <= n:
            max_size <<= 1
        max_size >>= 1
        
        while start % max_size != 0:
            max_size >>= 1
        
        result.append(cidr(int_to_ip(start), 32 - max_size.bit_length() + 1))
        start += max_size
        n -= max_size
    
    return result
Ставь 👍 и забирай 📚 Базу знаний

Задача: 154. Find Minimum in Rotated Sorted Array II Сложность: Hard Предположим, что массив длиной n, отсортированный в порядке возрастания, повернут от 1 до n раз. Например, массив nums = [0,1,4,4,5,6,7] может стать: [4,5,6,7,0,1,4], если он был повернут 4 раза. [0,1,4,4,5,6,7], если он был повернут 7 раз. Обратите внимание, что поворот массива [a[0], a[1], a[2], ..., a[n-1]] 1 раз приводит к массиву [a[n-1], a[0], a[1], a[2], ..., a[n-2]]. Для данного отсортированного и повернутого массива nums, который может содержать дубликаты, верните минимальный элемент этого массива. Необходимо максимально уменьшить количество операций. Пример:
Input: nums = [1,3,5]
Output: 1
👨‍💻 Алгоритм: 1️⃣Сравнение с правой границей: В классическом бинарном поиске мы бы сравнивали элемент в середине (nums[mid]) с искомым значением. В нашем случае мы сравниваем его с элементом, на который указывает правый указатель (nums[high]). 2️⃣Обновление указателей: Если элемент в середине находится в той же половине массива, что и элемент на правой границе (nums[mid] > nums[high]), минимальный элемент должен находиться в левой половине от mid. Следовательно, сдвигаем правый указатель на позицию mid. Если nums[mid] < nums[high], это указывает, что минимальный элемент находится в правой половине или равен mid. Сдвигаем правый указатель на mid. Если nums[mid] == nums[high], мы не можем быть уверены, в какой половине находится минимальный элемент из-за наличия дубликатов. В этом случае безопасно сдвинуть правый указатель на один шаг влево (high = high - 1), чтобы сузить область поиска без пропуска возможного минимального элемента. 3️⃣Итерация до сужения диапазона поиска: Продолжаем процесс, пока левый указатель не встретится с правым. В конечном итоге правый указатель укажет на минимальный элемент массива после всех поворотов. 😎 Решение:
class Solution:
    def findMin(self, nums: List[int]) -> int:
        low = 0
        high = len(nums) - 1
        while high > low:
            pivot = low + (high - low) // 2
            if nums[pivot] < nums[high]:
                high = pivot
            elif nums[pivot] > nums[high]:
                low = pivot + 1
            else:
                high -= 1
        return nums[low]
Ставь 👍 и забирай 📚 Базу знаний

Как IT-компании увеличить продажи с помощью вебинаров? Делимся гайдом для маркетологов IT-компаний с рекомендациями ведущих р
Как IT-компании увеличить продажи с помощью вебинаров? Делимся гайдом для маркетологов IT-компаний с рекомендациями ведущих российских разработчиков и экспертов МТС Линк. Вы узнаете: - Как правильно использовать онлайн-мероприятия для продвижения; - Как собрать 10 000 потенциальных клиентов из любой точки мира в одном месте; - Как увеличить узнаваемость бренда и создать комьюнити вокруг него; - Как оценить вклад онлайн-мероприятия в продвижение компании и правильно обработать лиды; Бонус: кейс IT-компании с доходимостью до вебинаров 70% Получите методичку бесплатно на сайте! Скачать #реклама 16+ mts-link.ru О рекламодателе

Задача: 480. Sliding Window Median Сложность: hard Медиана — это среднее значение в упорядоченном списке целых чисел. Если размер списка четный, среднего значения не существует, поэтому медианой считается среднее значение двух средних чисел. Например, если arr = [2, 3, 4], медиана равна 3. Например, если arr = [1, 2, 3, 4], медиана равна (2 + 3) / 2 = 2.5. Вам дан целочисленный массив nums и целое число k. Существует скользящее окно размера k, которое перемещается от самого левого края массива до самого правого. Вы можете видеть только k чисел в окне. Каждый раз скользящее окно перемещается вправо на одну позицию. Верните массив медиан для каждого окна в исходном массиве. Ответы с точностью до 10^-5 будут приниматься. Пример:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [1.00000,-1.00000,-1.00000,3.00000,5.00000,6.00000]
Explanation: 
Window position                Median
---------------                -----
[1  3  -1] -3  5  3  6  7        1
 1 [3  -1  -3] 5  3  6  7       -1
 1  3 [-1  -3  5] 3  6  7       -1
 1  3  -1 [-3  5  3] 6  7        3
 1  3  -1  -3 [5  3  6] 7        5
 1  3  -1  -3  5 [3  6  7]       6
👨‍💻 Алгоритм: 1⃣Сохраняйте числа в контейнере окна размера k, выполняя следующие операции: Вставка входящего элемента. Удаление выходящего элемента. 2⃣ Отсортируйте окно, чтобы найти медианы. Вместо того чтобы каждый раз копировать и сортировать k последовательных элементов из входных данных, вставляйте и удаляйте по одному элементу при каждом сдвиге окна. 3⃣ Поддерживайте окно в отсортированном состоянии до и после операций вставки и удаления. 😎 Решение:
from typing import List

def medianSlidingWindow(nums: List[int], k: int) -> List[float]:
    medians = []

    for i in range(len(nums) - k + 1):
        window = sorted(nums[i:i + k])

        if k % 2 == 1:
            medians.append(window[k // 2])
        else:
            medians.append((window[k // 2 - 1] + window[k // 2]) / 2)

    return medians
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1219. Path with Maximum Gold Сложность: medium В золотом руднике размером m x n каждая ячейка содержит целое число, представляющее количество золота в этой ячейке, или 0, если она пуста. Верните максимальное количество золота, которое вы можете собрать при следующих условиях: - Каждый раз, когда вы находитесь в ячейке, вы собираете всё золото из этой ячейки. - Из вашей позиции вы можете сделать один шаг влево, вправо, вверх или вниз. - Вы не можете посещать одну и ту же ячейку более одного раза. - Никогда не посещайте ячейку с 0 золотом. - Вы можете начинать и прекращать сбор золота с любой позиции в сетке, которая содержит золото. Пример:
Input: grid = [[0,6,0],[5,8,7],[0,9,0]]
Output: 24
Explanation:
[[0,6,0],
 [5,8,7],
 [0,9,0]]
Path to get the maximum gold, 9 -> 8 -> 7.
👨‍💻 Алгоритм: 1⃣Инициализация и подготовка: Инициализируйте константный массив DIRECTIONS для направления перемещений. Определите количество строк и столбцов в сетке. Инициализируйте переменную maxGold для хранения максимального количества собранного золота. 2⃣Функция DFS и обратный трек: Реализуйте функцию dfsBacktrack для поиска пути с максимальным золотом с помощью DFS и обратного трека. Обрабатывайте базовый случай, проверяя выход за пределы сетки или ячейки без золота. Пометьте текущую ячейку как посещённую и сохраните её значение. Исследуйте каждую из четырёх смежных ячеек и обновите максимальное количество золота, если найден лучший путь. Сбросьте текущую ячейку до её исходного значения для дальнейших исследований. 3⃣Поиск максимального золота: Используйте вложенные циклы для каждой ячейки в сетке, чтобы найти максимальное количество золота, начиная с этой ячейки, с помощью функции dfsBacktrack. Обновите maxGold при нахождении лучшего пути. Верните maxGold. 😎 Решение:
class Solution:
    def getMaximumGold(self, grid):
        def dfsBacktrack(grid, rows, cols, row, col):
            if row < 0 or col < 0 or row >= rows or col >= cols or grid[row][col] == 0:
                return 0
            originalVal = grid[row][col]
            grid[row][col] = 0
            maxGold = 0
            for dr, dc in directions:
                maxGold = max(maxGold, dfsBacktrack(grid, rows, cols, row + dr, col + dc))
            grid[row][col] = originalVal
            return maxGold + originalVal

        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
        rows, cols = len(grid), len(grid[0])
        maxGold = 0
        for row in range(rows):
            for col in range(cols):
                maxGold = max(maxGold, dfsBacktrack(grid, rows, cols, row, col))
        return maxGold
Ставь 👍 и забирай 📚 Базу знаний

Продвижение в Telegram с помощью Яндекс Директа ⚡Запустите продвижение в телеграм-каналах и привлекайте целевую аудиторию 📱
+3
Продвижение в Telegram с помощью Яндекс Директа ⚡Запустите продвижение в телеграм-каналах и привлекайте целевую аудиторию 📱 Таргетинг по тематикам, регионам и каналам в Telegram Попробовать #реклама yandex.ru О рекламодателе

Задача: 1273. Delete Tree Nodes Сложность: medium Дерево, укорененное в узле 0, задано следующим образом: количество узлов - nodes; значение i-го узла - value[i]; родитель i-го узла - parent[i]. Удалите все поддеревья, сумма значений узлов которых равна нулю. Верните количество оставшихся узлов в дереве. Пример:
Input: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-1]
Output: 2
👨‍💻 Алгоритм: 1⃣Постройте дерево из заданных узлов, значений и родителей. 2⃣Используйте постфиксный обход для вычисления суммы значений в каждом поддереве и помечайте узлы для удаления, если их сумма равна нулю. 3⃣Удалите отмеченные узлы и их поддеревья и верните количество оставшихся узлов. 😎 Решение:
def deleteTreeNodes(nodes, parent, value):
    from collections import defaultdict, deque
    
    tree = defaultdict(list)
    for i in range(nodes):
        if parent[i] != -1:
            tree[parent[i]].append(i)
    
    def dfs(node):
        total_sum = value[node]
        total_count = 1
        for child in tree[node]:
            child_sum, child_count = dfs(child)
            total_sum += child_sum
            total_count += child_count
        if total_sum == 0:
            return 0, 0
        return total_sum, total_count
    
    return dfs(0)[1]
Ставь 👍 и забирай 📚 Базу знаний

Бесплатный курс по дизайну: веб, графический и UX/UI Получи востребованные навыки: - создание дизайна сайтов и приложений - с
Бесплатный курс по дизайну: веб, графический и UX/UI Получи востребованные навыки: - создание дизайна сайтов и приложений - создание инфографики и карточек для маркетплейсов - работа в графическом редакторе Figma и др. Студенты курса в среднем зарабатывают от 68 000 ₽ уже во время обучения💰 Зарегистрироваться #реклама 16+ ydaev.ru О рекламодателе

Задача: 684. Redundant Connection Сложность: medium В этой задаче дерево — это неориентированный граф, который является связным и не содержит циклов. Вам дан граф, который изначально был деревом с n узлами, пронумерованными от 1 до n, и к которому добавили одно дополнительное ребро. Добавленное ребро соединяет две разные вершины, выбранные из 1 до n, и это ребро не существовало ранее. Граф представлен массивом edges длины n, где edges[i] = [ai, bi] указывает на то, что существует ребро между узлами ai и bi в графе. Верните ребро, которое можно удалить, чтобы результирующий граф стал деревом из n узлов. Если существует несколько ответов, верните тот, который встречается последним в исходных данных. Пример:
Input: edges = [[1,2],[1,3],[2,3]]
Output: [2,3]
👨‍💻 Алгоритм: 1⃣Для каждого ребра (u, v) создайте представление графа с использованием списка смежности. Это позволит легко выполнять обход в глубину (DFS) для проверки соединений между узлами. 2⃣Выполняйте обход в глубину для каждого ребра, временно удаляя его из графа. Проверьте, можно ли соединить узлы u и v с помощью обхода в глубину. Если узлы остаются соединенными, значит, это ребро является дублирующимся. 3⃣Верните дублирующееся ребро, которое встречается последним в исходных данных. Это обеспечит корректность решения, даже если существует несколько ответов. 😎 Решение:
class Solution:
    def __init__(self):
        self.seen = set()
        self.MAX_EDGE_VAL = 1000

    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        graph = [[] for _ in range(self.MAX_EDGE_VAL + 1)]

        for edge in edges:
            self.seen.clear()
            if graph[edge[0]] and graph[edge[1]] and self.dfs(graph, edge[0], edge[1]):
                return edge
            graph[edge[0]].append(edge[1])
            graph[edge[1]].append(edge[0])
        return []

    def dfs(self, graph: List[List[int]], source: int, target: int) -> bool:
        if source not in self.seen:
            self.seen.add(source)
            if source == target:
                return True
            for nei in graph[source]:
                if self.dfs(graph, nei, target):
                    return True
        return False
Ставь 👍 и забирай 📚 Базу знаний

Курс "Дизайн карточек для WB и Ozon". Бесплатно и с нуля Дизайнер карточек для маркетплейсов — востребованная и доходная проф
Курс "Дизайн карточек для WB и Ozon". Бесплатно и с нуля Дизайнер карточек для маркетплейсов — востребованная и доходная профессия 💰 Научись ей бесплатно! - Бесплатный доступ - Разбор ДЗ от наставника - Мощные кейсы в портфолио Узнать больше #реклама 16+ yudaevschool24.online О рекламодателе

Задача: 814. Binary Tree Pruning Сложность: medium Дан корень бинарного дерева. Верните то же дерево, в котором удалены все поддеревья (данного дерева), не содержащие 1. Поддерево узла node - это сам узел node и все узлы, являющиеся потомками node. Пример:
Input: root = [1,null,0,0,1]
Output: [1,null,0,null,1]
Explanation: 
Only the red nodes satisfy the property "every subtree not containing a 1".
The diagram on the right represents the answer.
👨‍💻 Алгоритм: 1⃣Используем функцию containsOne(node), которая сообщает, содержит ли поддерево в данном узле единицу, и обрезает все поддеревья, не содержащие единицу. 2⃣Например, если поддерево node.left не содержит единицу, то мы должны обрезать его через node.left = null. 3⃣Также нужно проверить родительский узел. Например, если дерево состоит из одного узла 0, то ответом будет пустое дерево. 😎 Решение:
class Solution:
    def pruneTree(self, root):
        def containsOne(node):
            if not node:
                return False
            
            leftContainsOne = containsOne(node.left)
            rightContainsOne = containsOne(node.right)
            
            if not leftContainsOne:
                node.left = None
            if not rightContainsOne:
                node.right = None
            
            return node.val == 1 or leftContainsOne or rightContainsOne
        
        return root if containsOne(root) else None
Ставь 👍 и забирай 📚 Базу знаний

Задача: 30. Substring with Concatenation of All Words Сложность: hard Вам дана строка s и массив строк-слов. Все строки-слова имеют одинаковую длину. Объединенная строка - это строка, которая точно содержит все строки из любой перестановки слов, которые были объединены. Например, если words = ["ab", "cd","ef"], то "abcdef", "abefcd", "cdabef", "cdefab", "efabcd" и "efcdab" являются связанными строками. "acdbef" не является объединенной строкой, потому что это не объединение какой-либо перестановки слов. Возвращает массив начальных индексов всех объединенных подстрок в s. Вы можете вернуть ответ в любом порядке. Пример:
  
Input: s = "barfoothefoobarman", words = ["foo","bar"]  
Output: [0,9]  
👨‍💻 Алгоритм: 1️⃣Создаем словарь с подсчетом количества слов в words. 2️⃣Проходим по строке s, проверяя подстроки длины, равной len(words) * len(words[0]). 3️⃣Проверяем, содержит ли подстрока все слова из words в нужном количестве. 😎 Решение:
from collections import defaultdict  

class Solution:  
    def findSubstring(self, s: str, words: List[str]) -> List[int]:  
        if not s or not words:  
            return []  

        word_count = defaultdict(int)  
        for word in words:  
            word_count[word] += 1  

        substr_len = len(words) * len(words[0])  
        word_len = len(words[0])  
        result = []  

        for i in range(len(s) - substr_len + 1):  
            seen = defaultdict(int)  
            for j in range(i, i + substr_len, word_len):  
                word = s[j:j+word_len]  
                if word in word_count:  
                    seen[word] += 1  
                    if seen[word] > word_count[word]:  
                        break  
                else:  
                    break  
            else:  
                result.append(i)  

        return result
Ставь 👍 и забирай 📚 Базу знаний

Надежные VDS-сервера в NetAngels от 73₽/месяц Подберем мощные VDS-сервер для любых задач. Техподдержка 24/7. Защита от DDoS-а
Надежные VDS-сервера в NetAngels от 73₽/месяц Подберем мощные VDS-сервер для любых задач. Техподдержка 24/7. Защита от DDoS-атак. Гибкая конфигурация. Бесплатный перенос VDS с сохранением всех данных. Выбери тариф под свои задачи: Старт (Для низкой нагрузки: хранение файлов, раздача статики и простые веб-проекты) Оптима (NVMe-диски для высокой скорости и баланс цены и производительности) Турбо (Элитный VDS на базе топового оборудования с высокочастотными процессорами) Про (Мощный VDS с гарантированными ресурсами для масштабных проектов) ТурбоПро (VDS уровня enterprise с гарантированными ядрами и высокочастотными процессорами) Ультра (Высокопроизводительный VDS для ресурсоемких проектов и корпоративных систем. В тариф включена поддержка GPU) Попробуйте VDS-сервер от NetAngels! Перейти на сайт #реклама 16+ netangels.ru О рекламодателе

Задача: 647. Palindromic Substrings Сложность: medium Если задана строка s, верните количество палиндромных подстрок в ней. Строка является палиндромом, если она читается так же, как задом наперед. Подстрока - это непрерывная последовательность символов в строке. Пример:
Input: s = "abc"
Output: 3
👨‍💻 Алгоритм: 1⃣Инициализируйте счетчик для подсчета палиндромных подстрок. 2⃣Для каждой позиции в строке используйте два метода расширения: один для палиндромов нечетной длины и один для палиндромов четной длины. 3⃣Расширяйте от центра, проверяя, является ли подстрока палиндромом, и увеличивайте счетчик, если условие выполняется. 😎 Решение:
def countSubstrings(s):
    def expandAroundCenter(left, right):
        count = 0
        while left >= 0 and right < len(s) and s[left] == s[right]:
            count += 1
            left -= 1
            right += 1
        return count
    
    total_count = 0
    for i in range(len(s)):
        total_count += expandAroundCenter(i, i)  # For odd length palindromes
        total_count += expandAroundCenter(i, i + 1)  # For even length palindromes
    return total_count
Ставь 👍 и забирай 📚 Базу знаний

Зарплата 207.000р у Middle-разработчика в Яндекс «В день уходит несколько часов на созвоны, в остальное время закрываю задачк
Зарплата 207.000р у Middle-разработчика в Яндекс «В день уходит несколько часов на созвоны, в остальное время закрываю задачки из спринта, редко перерабатываю. У компании топовый офис, но с коллективом как-то не заладилось. Радуюсь классному ДМС и стабильной зарплате» - middle разработчик из Яндекса. Бигтех по-русски - канал с реальными зарплатами и историями IT-специалистов российского БигТеха. Там уже опубликованы рассказы программистов Альфа-банка, Сбера и Тинькофф 🤯 Читайте: @bigtech_russia

Новинка Gipopo! Готовые блюда для тех, кто учится жевать Неизмельчённая еда в удобных тарелочках, которую осталось только разогреть в микроволновке – идеальное решение для малышей с 12 месяцев! Узнать больше #реклама gipopo-baby.ru О рекламодателе

Задача: 465. Optimal Account Balancing Сложность: medium Дан массив транзакций transactions, где transactions[i] = [fromi, toi, amounti] указывает на то, что человек с ID = fromi дал сумму amounti долларов человеку с ID = toi. Верните минимальное количество транзакций, необходимых для урегулирования долгов. Пример:
Input: transactions = [[0,1,10],[2,0,5]]
Output: 2
👨‍💻 Алгоритм: 1⃣Создать хеш-таблицу для хранения чистого баланса каждого человека. 2⃣Собрать все ненулевые чистые балансы в массив balance_list. 3⃣Определить рекурсивную функцию dfs(cur) для очистки всех балансов в диапазоне balance_list[0 ~ cur]: Игнорировать cur, если баланс уже равен 0. Пока balance_list[cur] = 0, переходить к следующему человеку, увеличивая cur на 1. Если cur = n, вернуть 0. В противном случае установить cost на большое значение, например, inf. Пройтись по индексу nxt от cur + 1, если balance_list[nxt] * balance_list[cur] < 0, Добавить баланс balance_list[cur] к balance_list[nxt]: balance_list[nxt] += balance_list[cur]. Рекурсивно вызвать dfs(cur + 1) как dfs(cur) = 1 + dfs(cur + 1). Убрать ранее переданный баланс от cur: balance_list[nxt] -= balance_list[cur] (откат). Повторить с шага 5 и отслеживать минимальное количество операций cost = min(cost, 1 + dfs(cur + 1)), найденных в итерации. Вернуть cost, когда итерация завершена. Вернуть dfs(0). 😎 Решение:
class Solution:
    def minTransfers(self, transactions: List[List[int]]) -> int:
        from collections import defaultdict
        
        credit_map = defaultdict(int)
        for t in transactions:
            credit_map[t[0]] += t[2]
            credit_map[t[1]] -= t[2]
        
        credit_list = [amount for amount in credit_map.values() if amount != 0]
        n = len(credit_list)
        
        def dfs(cur):
            while cur < n and credit_list[cur] == 0:
                cur += 1
            if cur == n:
                return 0
            cost = float('inf')
            for nxt in range(cur + 1, n):
                if credit_list[nxt] * credit_list[cur] < 0:
                    credit_list[nxt] += credit_list[cur]
                    cost = min(cost, 1 + dfs(cur + 1))
                    credit_list[nxt] -= credit_list[cur]
            return cost
        
        return dfs(0)
Ставь 👍 и забирай 📚 Базу знаний