uz
Feedback
Python | LeetCode

Python | LeetCode

Kanalga Telegram’da o‘tish
9 410
Obunachilar
+324 soatlar
-57 kunlar
-6230 kunlar
Postlar arxiv
Задача: 1059. All Paths from Source Lead to Destination Сложность: medium Учитывая ребра направленного графа, где edges[i] = [ai, bi] указывает на наличие ребра между вершинами ai и bi, и две вершины source и destination этого графа, определите, все ли пути, начинающиеся из source, заканчиваются в destination, то есть: существует ли хотя бы один путь из source в destination Если существует путь из source в node без исходящих ребер, то этот node равен destination. Количество возможных путей из source в destination - конечное число. Верните true тогда и только тогда, когда все пути из source ведут в destination. Пример:
Input: n = 3, edges = [[0,1],[0,2]], source = 0, destination = 2
Output: false
👨‍💻 Алгоритм: 1⃣Построение графа и проверка путей: Построить граф на основе входных данных. Использовать поиск в глубину (DFS) для проверки наличия всех путей от вершины source до вершины destination. 2⃣Проверка конечности путей: Проверить, что из всех вершин, достижимых от source, либо исходят ребра, либо они являются вершиной destination. Убедиться, что из любой вершины, не являющейся destination, исходят хотя бы одно ребро. 3⃣Рекурсивная проверка конечности путей: Рекурсивно проверять, что все пути из source заканчиваются в destination, избегая циклов и проверяя конечность всех путей. 😎 Решение:
def leadsToDestination(n, edges, source, destination):
    from collections import defaultdict
    
    graph = defaultdict(list)
    for a, b in edges:
        graph[a].append(b)
    
    visited = [0] * n
    
    def dfs(node):
        if visited[node] != 0:
            return visited[node] == 2
        if not graph[node]:
            return node == destination
        visited[node] = 1
        for neighbor in graph[node]:
            if not dfs(neighbor):
                return False
        visited[node] = 2
        return True

    return dfs(source)
Ставь 👍 и забирай 📚 Базу знаний

Айтишники, это вам — в телеграм есть комьюнити по каждому направлению в IT Там есть буквально всё: чаты для общения, тонны ма
Айтишники, это вам — в телеграм есть комьюнити по каждому направлению в IT Там есть буквально всё: чаты для общения, тонны материала(книги, курсы, ресурсы и гайды), свежие новости и конечно же мемы Выбирайте своё направление: 💩 Frontend 🐍 Python 🐧 Linux 👩‍💻 С/С++ 👩‍💻 C# 🤔 Хакинг & ИБ 📱 GitHub 🖥 SQL 👩‍💻 Сисадмин 🤟 DevOps ⚙️ Backend 🖥 Data Science 🧑‍💻 Java 🐞 Тестирование 🖥 PM / PdM 👩‍💻 GameDev 🧑‍💻 Golang 🤵‍♂️ IT-Митапы 🧑‍💻 PHP 💻 WebDev 🖥 Моб. Dev 🖥Анали.(SA&BA) 👩‍💻 Дизайн 🖥 Нейросети 💛 1C 🤓 Книги IT ➡️ Сохраняйте в закладки

Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп до150 000 рублей в месяц. Без опыта, нужен т
Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп до150 000 рублей в месяц. Без опыта, нужен только телефон, занятость 3-6 часов в день. Всему обучат на бесплатном курсе и после возьму на работу: ✅ 3 дня уроков по 30 минут ✅ Домашки с проверкой и оплатой бонусами ✅ Плачу 10 тыс за каждую выполненную домашку Все кто пройдет курс, получат сертификат от школы с образовательной лицензией. ⚡ Набор заканчивается завтра. 👍 Для регистрации жмите кнопку "Зарегистрироваться" Зарегистрироваться #реклама 16+ course.wildmanager.ru О рекламодателе

Задача: 944. Delete Columns to Make Sorted Сложность: easy Учитывая массив строк words, верните наименьшую строку, которая содержит каждую строку в words в качестве подстроки. Если существует несколько допустимых строк наименьшей длины, верните любую из них. Вы можете предположить, что ни одна строка в words не является подстрокой другой строки в words. Пример:
Input: strs = ["cba","daf","ghi"]
Output: 1
👨‍💻 Алгоритм: 1⃣Инициализировать переменную count для отслеживания количества столбцов, которые нужно удалить. 2⃣Пройти по каждому столбцу от 0 до длины строки. Для каждого столбца проверить, отсортированы ли символы лексикографически. Если столбец не отсортирован, увеличить count. 3⃣Вернуть count. 😎 Решение:
def minDeletionSize(strs):
    count = 0
    for col in range(len(strs[0])):
        for row in range(1, len(strs)):
            if strs[row][col] < strs[row - 1][col]:
                count += 1
                break
    return count
Ставь 👍 и забирай 📚 Базу знаний

Задача: 968. Binary Tree Cameras Сложность: hard Вам дан корень бинарного дерева. Мы устанавливаем камеры на узлы дерева, где каждая камера на узле может наблюдать за своим родителем, собой и своими непосредственными детьми. Верните минимальное количество камер, необходимых для наблюдения за всеми узлами дерева. Пример:
Input: root = [0,0,null,0,null,0,null,null,0]
Output: 2
Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.
👨‍💻 Алгоритм: 1⃣Рекурсивное решение (solve): Для каждого узла определите три состояния: - [State 0] Строгое поддерево: все узлы ниже этого узла покрыты, но не сам узел. - [State 1] Нормальное поддерево: все узлы ниже и включая этот узел покрыты, но на этом узле нет камеры. - [State 2] Установленная камера: все узлы ниже и включая этот узел покрыты, и на этом узле установлена камера. Рассчитайте эти состояния для левого и правого поддеревьев. 2⃣Рассчёт состояний: Чтобы покрыть строгое поддерево, дети этого узла должны находиться в состоянии 1. Чтобы покрыть нормальное поддерево без установки камеры на этом узле, дети этого узла должны находиться в состояниях 1 или 2, и по крайней мере один из этих детей должен быть в состоянии 2. Чтобы покрыть поддерево при установке камеры на этом узле, дети могут находиться в любом состоянии. 3⃣Минимальное количество камер: Запустите функцию solve на корневом узле и верните минимальное значение между состояниями 1 и 2. 😎 Решение:
class Solution:
    def minCameraCover(self, root: TreeNode) -> int:
        def solve(node):
            if not node:
                return 0, 0, float('inf')

            L = solve(node.left)
            R = solve(node.right)
            mL12 = min(L[1], L[2])
            mR12 = min(R[1], R[2])

            d0 = L[1] + R[1]
            d1 = min(L[2] + mR12, R[2] + mL12)
            d2 = 1 + min(L[0], mL12) + min(R[0], mR12)
            return d0, d1, d2

        return min(solve(root)[1:])
Ставь 👍 и забирай 📚 Базу знаний

Задача: 789. Escape The Ghosts Сложность: medium Вы играете в упрощенную игру PAC-MAN на бесконечной 2D-сетке. Вы начинаете в точке [0, 0], и у вас есть конечная точка target = [xtarget, ytarget], к которой вы пытаетесь добраться. На карте находятся несколько привидений, их начальные позиции заданы в виде двумерного массива ghosts, где ghosts[i] = [xi, yi] представляет начальную позицию i-го привидения. Все входные данные являются целочисленными координатами. Каждый ход вы и все привидения можете независимо выбирать перемещение на 1 единицу в любом из четырех основных направлений: север, восток, юг или запад, или оставаться на месте. Все действия происходят одновременно. Вы сможете сбежать, если и только если сможете достичь цели раньше, чем любое привидение достигнет вас. Если вы достигнете любой клетки (включая конечную точку) одновременно с привидением, это не считается побегом. Верните true, если можно сбежать независимо от того, как движутся привидения, иначе верните false. Пример:
Input: ghosts = [[1,0],[0,3]], target = [0,1]
Output: true
Explanation: You can reach the destination (0, 1) after 1 turn, while the ghosts located at (1, 0) and (0, 3) cannot catch up with you.
👨‍💻 Алгоритм: 1⃣Проверьте, что наше таксическое расстояние до цели меньше, чем расстояние от любого привидения до цели. 2⃣Если это так, мы можем гарантированно добраться до цели раньше любого привидения. 3⃣Если привидение может добраться до цели раньше нас или одновременно с нами, побег невозможен. 😎 Решение:
class Solution:
    def escapeGhosts(self, ghosts, target):
        def taxi(P, Q):
            return abs(P[0] - Q[0]) + abs(P[1] - Q[1])

        return all(taxi([0, 0], target) < taxi(ghost, target)
                   for ghost in ghosts)
Ставь 👍 и забирай 📚 Базу знаний

Задача: 901. Online Stock Span Сложность: medium Разработайте алгоритм, который собирает ежедневные котировки цен на некоторые акции и возвращает размах цены этой акции за текущий день. Размах цены акции за один день - это максимальное количество дней подряд (начиная с этого дня и в обратном направлении), в течение которых цена акции была меньше или равна цене этого дня. Например, если цены акции за последние четыре дня равны [7,2,1,2], а цена акции сегодня равна 2, то размах сегодняшнего дня равен 4, поскольку, начиная с сегодняшнего дня, цена акции была меньше или равна 2 в течение 4 дней подряд. Также, если цена акции за последние четыре дня равна [7,34,1,2], а цена акции сегодня равна 8, то размах сегодняшнего дня равен 3, так как начиная с сегодняшнего дня цена акции была меньше или равна 8 в течение 3 дней подряд. Реализация класса StockSpanner: StockSpanner() Инициализирует объект класса. int next(int price) Возвращает размах цены акции, учитывая, что сегодняшняя цена равна price. Пример:
Input
["StockSpanner", "next", "next", "next", "next", "next", "next", "next"]
[[], [100], [80], [60], [70], [60], [75], [85]]
Output
[null, 1, 1, 1, 2, 1, 4, 6]
👨‍💻 Алгоритм: 1⃣Инициализировать стек для хранения пар значений (цена, размах) и переменную для текущего индекса. 2⃣Для метода next: Установить начальный размах текущего дня равным 1. Пока стек не пуст и верхний элемент стека имеет цену меньше или равную текущей цене: Добавить размах верхнего элемента стека к текущему размаху. Удалить верхний элемент стека. 3⃣Добавить текущую цену и размах на вершину стека. Вернуть текущий размах. 😎 Решение:
class StockSpanner:
    def __init__(self):
        self.stack = []

    def next(self, price):
        span = 1
        while self.stack and self.stack[-1][0] <= price:
            span += self.stack.pop()[1]
        self.stack.append((price, span))
        return span
Ставь 👍 и забирай 📚 Базу знаний

Задача: 251. Flatten 2D Vector Сложность: medium Разработайте итератор для разворачивания двумерного вектора. Он должен поддерживать операции next и hasNext. Реализуйте класс Vector2D: Vector2D(int[][] vec) инициализирует объект двумерным вектором vec. next() возвращает следующий элемент из двумерного вектора и перемещает указатель на один шаг вперед. Вы можете предположить, что все вызовы next допустимы. hasNext() возвращает true, если в векторе еще остались элементы, и false в противном случае. Пример:
Input
["Vector2D", "next", "next", "next", "hasNext", "hasNext", "next", "hasNext"]
[[[[1, 2], [3], [4]]], [], [], [], [], [], [], []]
Output
[null, 1, 2, 3, true, true, 4, false]

Explanation
Vector2D vector2D = new Vector2D([[1, 2], [3], [4]]);
vector2D.next();    // return 1
vector2D.next();    // return 2
vector2D.next();    // return 3
vector2D.hasNext(); // return True
vector2D.hasNext(); // return True
vector2D.next();    // return 4
vector2D.hasNext(); // return False
👨‍💻 Алгоритм: 1️⃣Инициализация: Установите указатель position так, чтобы он указывал на следующий элемент массива, который должен быть возвращен методом next(). Это обеспечивает, что position всегда готов к получению следующего действительного элемента. 2️⃣Проверка доступности: Реализуйте метод hasNext(), который просто проверяет, находится ли индекс position в пределах допустимых индексов массива nums. Этот метод вернет true, если position указывает на действительный индекс, и false в противном случае. 3️⃣Получение следующего элемента: Метод next() возвращает элемент в текущей позиции position и продвигает указатель position на следующий индекс. Эта операция обеспечивает, что после вызова next(), position обновляется и указывает на следующий элемент, готовый к следующему вызову next(). 😎 Решение:
class Vector2D:
    def __init__(self, v):
        self.nums = [num for inner_list in v for num in inner_list]
        self.position = -1

    def next(self):
        self.position += 1
        return self.nums[self.position]

    def hasNext(self):
        return self.position + 1 < len(self.nums)
Ставь 👍 и забирай 📚 Базу знаний

Задача: 907. Sum of Subarray Minimums Сложность: medium Учитывая массив целых чисел arr, найдите сумму min(b), где b находится в каждом (смежном) подмассиве arr. Поскольку ответ может быть большим, верните ответ по модулю 109 + 7. Пример:
Input: arr = [3,1,2,4]
Output: 17
👨‍💻 Алгоритм: 1⃣Использовать монотонный стек для нахождения ближайшего меньшего элемента слева и справа для каждого элемента массива. 2⃣Использовать эту информацию для вычисления количества подмассивов, где каждый элемент является минимальным. 3⃣Вычислить сумму минимальных значений для всех подмассивов и вернуть результат по модулю 10^9 + 7. 😎 Решение:
def sumSubarrayMins(arr):
    MOD = 10**9 + 7
    n = len(arr)
    left = [0] * n
    right = [0] * n
    stack = []

    for i in range(n):
        while stack and arr[stack[-1]] > arr[i]:
            stack.pop()
        left[i] = i + 1 if not stack else i - stack[-1]
        stack.append(i)

    stack = []

    for i in range(n - 1, -1, -1):
        while stack and arr[stack[-1]] >= arr[i]:
            stack.pop()
        right[i] = n - i if not stack else stack[-1] - i
        stack.append(i)

    result = sum(a * l * r for a, l, r in zip(arr, left, right)) % MOD
    return result
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1269. Number of Ways to Stay in the Same Place After Some Steps Сложность: hard У вас есть указатель на индекс 0 в массиве размера arrLen. На каждом шаге вы можете перемещаться на 1 позицию влево, на 1 позицию вправо в массиве или оставаться на том же месте (указатель ни в коем случае не должен находиться за пределами массива). Учитывая два целых числа steps и arrLen, верните количество способов, при которых указатель все еще находится на индексе 0 после ровно шагов. Поскольку ответ может быть слишком большим, верните его по модулю 10^9 + 7. Пример:
Input: steps = 3, arrLen = 2
Output: 4
👨‍💻 Алгоритм: 1⃣Инициализируйте массив для хранения количества способов достижения каждого индекса на каждом шаге. 2⃣Используйте динамическое программирование для подсчета количества способов достижения каждого индекса на каждом шаге. 3⃣Используйте динамическое программирование для подсчета количества способов достижения каждого индекса на каждом шаге. 😎 Решение:
def numWays(steps, arrLen):
    mod = 10**9 + 7
    max_pos = min(arrLen - 1, steps)
    dp = [0] * (max_pos + 1)
    dp[0] = 1
    for _ in range(steps):
        new_dp = [0] * (max_pos + 1)
        for i in range(max_pos + 1):
            new_dp[i] = dp[i] % mod
            if i > 0:
                new_dp[i] = (new_dp[i] + dp[i - 1]) % mod
            if i < max_pos:
                new_dp[i] = (new_dp[i] + dp[i + 1]) % mod
        dp = new_dp
    return dp[0]
Ставь 👍 и забирай 📚 Базу знаний

Repost from Идущий к IT
🔥 Записал видос "Как за 3 минуты настроить Автоотклики на вакансии HeadHunter" больше не придется заниматься этой унылой рут
🔥 Записал видос "Как за 3 минуты настроить Автоотклики на вакансии HeadHunter" больше не придется заниматься этой унылой рутиной 📺 Видео: https://youtu.be/G_FOwEGPwlw

Задача: 1100. Find K-Length Substrings With No Repeated Characters Сложность: medium Дана строка s и целое число k. Верните количество подстрок в s длиной k, которые не содержат повторяющихся символов. Пример:
Input: s = "havefunonleetcode", k = 5
Output: 6
Explanation: There are 6 substrings they are: 'havef','avefu','vefun','efuno','etcod','tcode'.
👨‍💻 Алгоритм: 1⃣Если k > 26, верните 0, так как не может быть строки длиной более 26 символов с уникальными символами. Для остальных случаев, где k <= 26, проверьте каждую подстроку длиной k на наличие повторяющихся символов. 2⃣Итерация по строке s от индекса 0 до n - k (включительно), где n - длина строки s: Для каждого индекса i: Инициализируйте флаг isUnique как true и массив частот размером 26 для подсчета частот каждого символа. Итерируйте следующие k символов и увеличивайте частоту каждого встреченного символа в массиве частот. Если частота любого символа становится больше 1, установите isUnique в false и прекратите итерацию. Если после итерации по k символам флаг isUnique все еще равен true, увеличьте счетчик ответов на 1. 3⃣Верните количество подстрок без повторяющихся символов после итерации по всем индексам от 0 до n - k. 😎 Решение:
class Solution:
    def numKLenSubstrNoRepeats(self, s: str, k: int) -> int:
        if k > 26:
            return 0
        
        n = len(s)
        answer = 0
        
        for i in range(n - k + 1):
            freq = [0] * 26
            is_unique = True
            
            for j in range(i, i + k):
                freq[ord(s[j]) - ord('a')] += 1
                
                if freq[ord(s[j]) - ord('a')] > 1:
                    is_unique = False
                    break
            
            if is_unique:
                answer += 1
        
        return answer
Ставь 👍 и забирай 📚 Базу знаний

Задача: 740. Delete and Earn Сложность: medium Вам дан целочисленный массив nums. Вы хотите максимизировать количество очков,
Задача: 740. Delete and Earn Сложность: medium Вам дан целочисленный массив nums. Вы хотите максимизировать количество очков, выполнив следующую операцию любое количество раз: Выберите любой элемент nums[i] и удалите его, чтобы заработать nums[i] очков. После этого вы должны удалить каждый элемент, равный nums[i] - 1, и каждый элемент, равный nums[i] + 1. Верните максимальное количество очков, которое вы можете заработать, применив вышеуказанную операцию некоторое количество раз. Пример:
Input: nums = [3,4,2]
Output: 6
👨‍💻 Алгоритм: 1⃣Подсчитайте количество каждого числа в массиве nums. 2⃣Используйте динамическое программирование для расчета максимальных очков, которые можно заработать, используя накопленный результат для чисел, меньших текущего. Добавьте текущий день в стек. 3⃣Для каждого числа num в nums, учитывайте два случая: не брать число или взять число и добавить его очки. 😎 Решение:
def deleteAndEarn(nums):
    from collections import Counter
    
    count = Counter(nums)
    prev = None
    avoid = using = 0
    
    for num in sorted(count):
        if num - 1 != prev:
            new_avoid, new_using = max(avoid, using), num * count[num] + max(avoid, using)
        else:
            new_avoid, new_using = max(avoid, using), num * count[num] + avoid
        avoid, using = new_avoid, new_using
        prev = num
    
    return max(avoid, using)
Ставь 👍 и забирай 📚 Базу знаний

Задача: 849. Maximize Distance to Closest Person Сложность: medium Вам дан массив, представляющий ряд сидений, где seats[i] = 1 означает, что на i-м месте сидит человек, а seats[i] = 0 означает, что i-е место пусто (индексация с нуля). Есть по крайней мере одно пустое место и по крайней мере один человек, сидящий на месте. Алекс хочет сесть на такое место, чтобы расстояние между ним и ближайшим к нему человеком было максимальным. Верните это максимальное расстояние до ближайшего человека. Пример:
Input: seats = [1,0,0,0,1,0,1]
Output: 2
Explanation: 
If Alex sits in the second open seat (i.e. seats[2]), then the closest person has distance 2.
If Alex sits in any other open seat, the closest person has distance 1.
Thus, the maximum distance to the closest person is 2.
👨‍💻 Алгоритм: 1⃣Следите за prev, занятым местом слева или на текущей позиции i, и future, занятым местом справа или на текущей позиции i. 2⃣Для каждого пустого места i определите ближайшее занятие места как min(i - prev, future - i), с учетом, что i - prev считается бесконечностью, если слева нет занятого места, и future - i считается бесконечностью, если справа нет занятого места. 3⃣Найдите и верните максимальное расстояние до ближайшего занятого места. 😎 Решение:
class Solution:
    def maxDistToClosest(self, seats: List[int]) -> int:
        n = len(seats)
        prev = -1
        future = 0
        ans = 0

        for i in range(n):
            if seats[i] == 1:
                prev = i
            else:
                while future < n and (seats[future] == 0 or future < i):
                    future += 1
                left = n if prev == -1 else i - prev
                right = n if future == n else future - i
                ans = max(ans, min(left, right))
        
        return ans
Ставь 👍 и забирай 📚 Базу знаний

Задача: 678. Valid Parenthesis String Сложность: medium Создайте карту, которая позволяет выполнять следующие действия: Отображает строковый ключ на заданное значение. Возвращает сумму значений, у которых ключ имеет префикс, равный заданной строке. Реализуйте класс MapSum: Дана строка s, содержащая только три типа символов: '(', ')' и '*'. Вернуть true, если s является допустимой. Следующие правила определяют допустимую строку: Любая открывающая скобка '(' должна иметь соответствующую закрывающую скобку ')'. Любая закрывающая скобка ')' должна иметь соответствующую открывающую скобку '('. Открывающая скобка '(' должна идти перед соответствующей закрывающей скобкой ')'. '*' может рассматриваться как одна закрывающая скобка ')', одна открывающая скобка '(' или пустая строка "". Пример:
Input: s = "()"
Output: true
Example 2:
👨‍💻 Алгоритм: 1⃣Инициализировать 2D вектор memo размером s.size() x s.size() - 1, представляющий неинициализированное состояние. Вызвать вспомогательную функцию isValidString с начальными параметрами index = 0, openCount = 0 и строкой s. Вернуть результат isValidString. 2⃣Вспомогательная функция isValidString. Базовый случай: если index достиг конца строки (index == s.size.), вернуть true, если openCount равен 0 (все скобки сбалансированы), и false в противном случае. Проверить, был ли результат для текущего index и openCount уже вычислен (мемоизирован) в memo. Если да, вернуть мемоизированный результат. Инициализировать isValid как false. Если текущий символ s[index] равен '*': Попробовать трактовать '*' как '(' и вызвать isValidString рекурсивно с index + 1 и openCount + 1. Если рекурсивный вызов вернет true, обновить isValid на true. Если openCount не равен нулю, попробовать трактовать '*' как ')' и вызвать isValidString рекурсивно с index + 1 и openCount - 1. Если рекурсивный вызов вернет true, обновить isValid на true. Попробовать трактовать '*' как пустой символ и вызвать isValidString рекурсивно с index + 1 и тем же openCount. Если рекурсивный вызов вернет true, обновить isValid на true. 3⃣Продолжение функции isValidString. Если текущий символ s[index] равен '(': Вызвать isValidString рекурсивно с index + 1 и openCount + 1. Обновить isValid с результатом рекурсивного вызова. Если текущий символ s[index] равен ')': Если openCount не равен нулю (есть открытые скобки), вызвать isValidString рекурсивно с index + 1 и openCount - 1. Обновить isValid с результатом рекурсивного вызова. Мемоизировать результат isValid в memo[index][openCount]. Вернуть isValid. 😎 Решение:
class Solution:
    def checkValidString(self, s: str) -> bool:
        memo = [[-1] * len(s) for _ in range(len(s))]
        return self.isValidString(0, 0, s, memo)

    def isValidString(self, index: int, openCount: int, s: str, memo: list) -> bool:
        if index == len(s):
            return openCount == 0

        if memo[index][openCount] != -1:
            return memo[index][openCount] == 1

        isValid = False

        if s[index] == '*':
            isValid = self.isValidString(index + 1, openCount + 1, s, memo)
            if openCount > 0:
                isValid = isValid or self.isValidString(index + 1, openCount - 1, s, memo)
            isValid = isValid or self.isValidString(index + 1, openCount, s, memo)
        elif s[index] == '(':
            isValid = self.isValidString(index + 1, openCount + 1, s, memo)
        elif openCount > 0:
            isValid = self.isValidString(index + 1, openCount - 1, s, memo)

        memo[index][openCount] = 1 if isValid else 0
        return isValid
Ставь 👍 и забирай 📚 Базу знаний

Задача: 401. Binary Watch Сложность: easy Бинарные часы имеют 4 светодиода сверху для представления часов (0-11) и 6 светодио
Задача: 401. Binary Watch Сложность: easy Бинарные часы имеют 4 светодиода сверху для представления часов (0-11) и 6 светодиодов снизу для представления минут (0-59). Каждый светодиод представляет ноль или единицу, при этом младший разряд находится справа. Пример:
Input: turnedOn = 1
Output: ["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]
👨‍💻 Алгоритм: 1⃣Генерация всех возможных комбинаций: Переберите все возможные значения для часов и минут. Используйте битовые операции для подсчета количества единиц в бинарном представлении числа. 2⃣Проверка количества горящих светодиодов: Для каждой комбинации проверьте, соответствует ли сумма единиц в бинарном представлении часов и минут заданному количеству горящих светодиодов. 3⃣Форматирование результата: Если комбинация часов и минут соответствует условию, отформатируйте их в виде строки "часы:минуты" и добавьте в список результатов. 😎 Решение:
class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        results = []
        for h in range(12):
            for m in range(60):
                if bin(h).count('1') + bin(m).count('1') == turnedOn:
                    results.append(f"{h}:{m:02d}")
        return results
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1202. Smallest String With Swaps Сложность: medium Вам дана строка s и массив пар индексов в строке pairs, где pairs[i] = [a, b] указывает на 2 индекса (начиная с 0) в строке. Вы можете менять местами символы в любой паре индексов в заданных парах любое количество раз. Верните лексикографически наименьшую строку, которую можно получить после выполнения перестановок. Пример:
Input: s = "dcab", pairs = [[0,3],[1,2]]
Output: "bacd"
Explaination: 
Swap s[0] and s[3], s = "bcad"
Swap s[1] and s[2], s = "bacd"
👨‍💻 Алгоритм: 1⃣Создание списка смежности: Итеративно пройдитесь по парам и создайте список смежности adj, где adj[source] содержит все смежные вершины вершины source. 2⃣Обход графа и сбор индексов и символов: Итеративно пройдитесь по индексам от 0 до s.size() - 1. Для каждого индекса vertex: - выполните DFS, если вершина еще не посещена (visited[vertex] = false). - во время выполнения DFS сохраняйте vertex в список indices и символ s[vertex] в список characters. 3⃣Сортировка и построение результирующей строки: Отсортируйте списки indices и characters. Пройдитесь по индексам и символам, и разместите i-й символ в i-й индекс результирующей строки smallestString. Верните smallestString. 😎 Решение:
class Solution:
    def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
        adj = defaultdict(list)
        for a, b in pairs:
            adj[a].append(b)
            adj[b].append(a)
        
        visited = [False] * len(s)
        s = list(s)
        
        def dfs(node, indices, chars):
            visited[node] = True
            indices.append(node)
            chars.append(s[node])
            for neighbor in adj[node]:
                if not visited[neighbor]:
                    dfs(neighbor, indices, chars)
        
        for i in range(len(s)):
            if not visited[i]:
                indices = []
                chars = []
                dfs(i, indices, chars)
                indices.sort()
                chars.sort()
                for index, char in zip(indices, chars):
                    s[index] = char
        
        return ''.join(s)
Ставь 👍 и забирай 📚 Базу знаний

Задача: 75. Sort Colors Сложность: medium Дан массив nums, содержащий n объектов, окрашенных в красный, белый или синий цвет.
Задача: 75. Sort Colors Сложность: medium Дан массив nums, содержащий n объектов, окрашенных в красный, белый или синий цвет. Отсортируйте их на месте так, чтобы объекты одного цвета находились рядом, а цвета располагались в порядке красный, белый и синий. Мы будем использовать целые числа 0, 1 и 2 для обозначения красного, белого и синего цветов соответственно. Вы должны решить эту задачу без использования функции сортировки библиотеки. Пример:
Input: nums = [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
👨‍💻 Алгоритм: 1️⃣Инициализация крайней правой границы нулей: p0 = 0. Во время выполнения алгоритма nums[idx < p0] = 0. 2️⃣Инициализация крайней левой границы двоек: p2 = n - 1. Во время выполнения алгоритма nums[idx > p2] = 2. 3️⃣Инициализация индекса текущего элемента для рассмотрения: curr = 0. Пока curr <= p2: Если nums[curr] = 0: поменять местами элементы с индексами curr и p0, и сдвинуть оба указателя вправо. Если nums[curr] = 2: поменять местами элементы с индексами curr и p2. Сдвинуть указатель p2 влево. Если nums[curr] = 1: сдвинуть указатель curr вправо. 😎 Решение:
class Solution:
    def sortColors(self, nums: List[int]) -> None:
        p0 = curr = 0
        p2 = len(nums) - 1

        while curr <= p2:
            if nums[curr] == 0:
                nums[p0], nums[curr] = nums[curr], nums[p0]
                p0 += 1
                curr += 1
            elif nums[curr] == 2:
                nums[curr], nums[p2] = nums[p2], nums[curr]
                p2 -= 1
            else:
                curr += 1
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1318. Minimum Flips to Make a OR b Equal to c Сложность: medium Даны три положительных числа a, b и c. Верните минимальное количество переворотов, необходимых в некоторых битах a и b, чтобы сделать (a OR b == c) (побитовая операция OR). Операция переворота состоит из изменения любого отдельного бита с 1 на 0 или с 0 на 1 в их двоичном представлении. Пример:
Input: a = 2, b = 6, c = 5
Output: 3
Explanation: After flips a = 1 , b = 4 , c = 5 such that (a OR b == c)
👨‍💻 Алгоритм: 1⃣Инициализируйте переменную answer как 0, которая будет использоваться для отслеживания минимального количества необходимых переворотов. 2⃣Итеративно обрабатывайте каждый бит двоичного представления чисел a, b и c одновременно: Если (c & 1) == 0, обновите answer как answer += (a & 1) + (b & 1). Если (c & 1) == 1, и если оба значения a & 1 и b & 1 равны 0, увеличьте answer на 1. 3⃣Сдвигайте все числа вправо с помощью a >>= 1, b >>= 1, c >>= 1. Если все числа равны 0, верните answer, в противном случае, повторите шаги 2 и 3. 😎 Решение:
class Solution:
    def minFlips(self, a: int, b: int, c: int) -> int:
        answer = 0
        while a != 0 or b != 0 or c != 0:
            if (c & 1) == 1:
                if (a & 1) == 0 and (b & 1) == 0:
                    answer += 1
            else:
                answer += (a & 1) + (b & 1)
            a >>= 1
            b >>= 1
            c >>= 1
        return answer
Ставь 👍 и забирай 📚 Базу знаний

Задача: 288. Unique Word Abbreviation Сложность: medium Сокращение слова — это объединение его первой буквы, количества символов между первой и последней буквой и последней буквы. Если слово состоит только из двух символов, то оно является сокращением само по себе. Например: dog --> d1g, потому что между первой буквой 'd' и последней буквой 'g' одна буква. internationalization --> i18n, потому что между первой буквой 'i' и последней буквой 'n' 18 букв. it --> it, потому что любое слово из двух символов является своим собственным сокращением. Реализуйте класс ValidWordAbbr: ValidWordAbbr(String[] dictionary) Инициализирует объект со словарем слов. boolean isUnique(string word) Возвращает true, если выполняется одно из следующих условий (в противном случае возвращает false): В словаре нет слова, сокращение которого равно сокращению слова word. Для любого слова в словаре, сокращение которого равно сокращению слова word, это слово и word одинаковы. Пример:
Input
["ValidWordAbbr", "isUnique", "isUnique", "isUnique", "isUnique", "isUnique"]
[[["deer", "door", "cake", "card"]], ["dear"], ["cart"], ["cane"], ["make"], ["cake"]]
Output
[null, false, true, false, true, true]

Explanation
ValidWordAbbr validWordAbbr = new ValidWordAbbr(["deer", "door", "cake", "card"]);
validWordAbbr.isUnique("dear"); // return false, dictionary word "deer" and word "dear" have the same abbreviation "d2r" but are not the same.
validWordAbbr.isUnique("cart"); // return true, no words in the dictionary have the abbreviation "c2t".
validWordAbbr.isUnique("cane"); // return false, dictionary word "cake" and word "cane" have the same abbreviation  "c2e" but are not the same.
validWordAbbr.isUnique("make"); // return true, no words in the dictionary have the abbreviation "m2e".
validWordAbbr.isUnique("cake"); // return true, because "cake" is already in the dictionary and no other word in the dictionary has "c2e" abbreviation.
👨‍💻 Алгоритм: 1⃣Инициализация: Создайте словарь сокращений abbrDict, который будет хранить сокращения слов в виде ключей и булевы значения, указывающие, уникально ли сокращение. Создайте множество dict, содержащее все слова из словаря, чтобы быстро проверять наличие слова в словаре. 2⃣Генерация сокращений: При инициализации объекта ValidWordAbbr пройдите через каждое слово в словаре и создайте его сокращение. Если сокращение уже существует в abbrDict, установите значение в false (не уникальное). В противном случае установите значение в true (уникальное). 3⃣Проверка уникальности: Для метода isUnique создайте сокращение для входного слова и проверьте, есть ли это сокращение в abbrDict. Если сокращение отсутствует в abbrDict, возвращайте true. Если сокращение присутствует и оно уникально, проверьте, есть ли это слово в словаре. Если да, возвращайте true, в противном случае - false. 😎 Решение:
class ValidWordAbbr:
    def __init__(self, dictionary: List[str]):
        self.abbr_dict = {}
        self.dict = set(dictionary)
        for word in self.dict:
            abbr = self.to_abbr(word)
            self.abbr_dict[abbr] = not self.abbr_dict.get(abbr, False)

    def isUnique(self, word: str) -> bool:
        abbr = self.to_abbr(word)
        has_abbr = self.abbr_dict.get(abbr)
        return has_abbr is None or (has_abbr and word in self.dict)

    def to_abbr(self, word: str) -> str:
        n = len(word)
        if n <= 2:
            return word
        return f"{word[0]}{n - 2}{word[-1]}"
Ставь 👍 и забирай 📚 Базу знаний