главная новое лучшее написать
неделя месяц год вечное
посты пользователи ответы
3

Ссылка на задачу – 3174. Clear Digits.

📌 Описание задачи

Дана строка s, содержащая буквы и цифры. Из неё возможно удалять цифры только путем выполнения следующей операции:

Вернуть итоговую строку после итеративного выполнения указанной операции до исчезновения всех цифр.

💡 Идея

Достаточно легко придумать алгоритм, формирующий ответ справа-налево (просто запоминаем, сколько символов нужно скипнуть после встреченных цифр).

Мы же реализуем решение с прямым (слева-направо) обходом строки без необходимости переворачивания результата.

⚙ Подробности подхода

  1. Инициализируем буфер размером s.len() (заполняем заглушками '\0').

Читать дальше →

ответить
3

Очередная наша задача - 3381. Maximum Subarray Sum With Length Divisible by K

Описание задачи

Дано целое число k и массив чисел nums. Необходимо найти максимальную сумму подмассива, длина которого кратна k.

🚀 Идея

Данная задача расширяет классический алгоритм нахождения максимальной суммы подмассива (алгоритм Кадане) для случаев, когда длина подмассива должна быть кратной k. Чтобы учесть это условие, мы перебираем все смещения в полуинтервале [0,k) и анализируем подмассивы с шагом k.

🔍 Подход

  1. Префиксные суммы:
    • Вычисляем массив префиксных сумм, чтобы быстро находить сумму любого подмассива.
  2. Перебор смещений:
    • Итерируем по всем возможным начальным смещениям [0,k), чтобы обрабатывать подмассивы длиной, кратной k.
  3. Модификация алгоритма Кадане:
    • Для каждого смещения применяем алгоритм нахождения максимальной суммы подмассива.
    • Если текущая сумма становится отрицательной, начинаем новый расчет с текущей позиции (сброс индекса начала подмассива).

Читать дальше →

ответить
3

Начну-ка я минипроект по разбору ежедневных задач с LeetCode.
Решения будут на раст, ибо: модно, стильно, молодёжно!

Rust идеально подходит для задач с LeetCode благодаря высокой производительности, безопасному управлению памятью и удобным инструментам для работы с данными, обеспечивая компактный и надёжный код.

Надеюсь, такой контент будет полезен аудитории.

ответить
3

Сегодня у нас еще одна задача на аккуратное манипулирование индексами 2337. Move Pieces to Obtain a String.

Описание задачи

Даны две строки start и target длины n, содержащие символы 'L', 'R' и '_'.

Идея 🧠

Задача сводится к тому, чтобы проверить, совпадают ли позиции и направления символов 'L' и 'R' в двух строках с учётом их ограничений на движение. Мы используем итерацию по строкам одновременно, отслеживая доступные символы 'L' и 'R' через счётчики.

Подход 🛠️

  1. Используем метод as_bytes(), чтобы быстро перебрать символы в виде байтов.
  2. Одновременно проходим по обеим строкам:
    • Если видим 'L' в target, увеличиваем счётчик доступных 'L'.
    • Если видим 'L' в start, проверяем, есть ли доступный 'L', и уменьшаем счётчик.

Читать дальше →

ответить
3

Ссылка на задачу — 1415. The k-th Lexicographical String of All Happy Strings of Length n.

📝 Описание задачи

"Счастливая строка" – это строка длины n, состоящая только из символов ['a', 'b', 'c'], в которой нет двух одинаковых подряд идущих символов.
Нужно найти k-ю счастливую строку в лексикографическом порядке, либо вернуть "", если таких строк меньше k.

💡 Идея

Рассмотрим связь счастливых строк с двоичными строками.
Каждая счастливая строка:

Таким образом, двоичное представление k-1 почти полностью определяет структуру требуемой строки (без первого символа).
Мы можем использовать биты 0 и 1 из этого двоичного представления, чтобы выбирать между двумя допустимыми символами при итеративной генерации каждого следующего символа конкретной счастливой строки. 🚀

🔍 Детали подхода

  1. Определяем количество возможных строк с фиксированным первым символом:

Читать дальше →

ответить
3

Ссылка на задачу — 1524. Number of Sub-arrays With Odd Sum.

📌 Описание задачи

Дан массив целых чисел arr. Необходимо найти количество подмассивов с нечётной суммой.
Так как ответ может быть очень большим, его необходимо вернуть по модулю 10⁹+7.

💡 Идея

Вместо явного перебора всех подмассивов (O(N²)), можно следить за чётностью суммы префикса.
Ключевое наблюдение:

🛠 Детали подхода

  1. Следим за чётностью префиксной суммы, храня в prefix_parity (0 - чётная, 1 - нечётная).
  2. Считаем количество чётных (even_count) и нечётных (odd_count) префиксных сумм.
  3. Используем fold для итеративного обновления результата.
  4. Добавляем соответствующие значения к result:
    • Если prefix_parity чётный, к result прибавляем odd_count.
    • Если prefix_parity нечётный, к result прибавляем even_count.

⏳ Асимптотика

💻 Исходный код

impl Solution {
    pub fn num_of_subarrays(arr: Vec<i32>) -> i32 {
        const MODULO: i32 = 1_000_000_007;

        let (result, _, _, _) = arr.into_iter()
            .fold((0, 0, 0, 1), |(result, prefix_parity, odd_count, even_count), num| {
                match(prefix_parity + num) % 2 {
                    0 => // Even prefix → account subarrays from odd prefixes
                        ((result + odd_count) % MODULO, 0, odd_count, even_count + 1),
                    _ => // Odd prefix → account subarrays from even prefixes
                        ((result + even_count) % MODULO, 1, odd_count + 1, even_count),
                }
            });

        result
    }
}

Tags: #rust #algorithms #prefixsum

ответить
3

Следующая задача для разбора - 1462. Course Schedule IV

✨ Описание задачи

У нас есть numCourses курсов, пронумерованных от 0 до numCourses - 1.
Даны:

Нужно вернуть массив булевых значений, где для каждого запроса ответ — true, если курс u является прямым или косвенным предшественником курса v; или false, если нет.

💡 Идея

Представим зависимости курсов в виде графа, где вершины — это курсы, а ребра указывают на зависимости между ними. Наша цель — определить, существует ли путь между двумя вершинами графа. Для этого можно использовать алгоритм Флойда-Уоршелла, чтобы вычислить транзитивное замыкание графа.

🛠️ Подробности подхода

  1. Инициализация матрицы зависимостей: Создаем булевую матрицу n x n, где dep_matrix[i][j] обозначает, что курс i является предшественником курса j.
  2. Заполнение прямых зависимостей: На основе массива prerequisites отмечаем прямые зависимости в матрице.

Читать дальше →

ответить
3

В нашей новой задаче - 1765. Map of Highest Peak продолжим закреплять работу с семейством простых графовых алгоритмов.

📜 Описание задачи

Вам дана матрица isWater размером m×n, где:

Требуется назначить высоты каждой клетке таким образом, чтобы:

  1. Высота каждой клетки была неотрицательной.
  2. Высота любой клетки с водой была равна 0.
  3. Абсолютная разница высот у соседних клеток не превышала 1.
  4. Максимальная высота в назначенной карте была как можно больше.

💡 Идея

Мы используем поиск в ширину с несколькими источниками (multi-source BFS), начиная с клеток воды (высота 0).
На каждом шаге ближайшие клетки суши получают высоту на 1 больше текущей.
Этот метод гарантирует, что все клетки суши получают наилучшую из возможных высот, что приводит к максимизации самой высокой высоты в матрице.

🛠 Подробности подхода

  1. Инициализация:
    • Создаём очередь и добавляем в неё все клетки воды, помечая их высотой 0.

Читать дальше →

ответить
3

Ссылка на задачу — 873. Length of Longest Fibonacci Subsequence.

📌 Описание задачи

Дан монотонно возрастающий массив arr. Нужно найти длину самой длинной фибоначчиевой подпоследовательности, где каждые три последовательных элемента x, y, z удовлетворяют свойству: z = x + y

Если такой подпоследовательности нет, вернуть 0.

💡 Идея

📌 Подробности метода

  1. Перебираем z = arr[k], начиная с k = 2, так как нужны минимум 3 числа.
  2. Будем использовать два указателя (front и back) на arr[..k]:
    • front движется вперёд (x увеличивается).
    • back движется назад (y уменьшается).
  3. Сравниваем x + y и z:

Читать дальше →

1 ответ
3

Следующая наша задача - 1014. Best Sightseeing Pair.

Описание задачи 📝

Дано: массив values, где

Требуется: найти пару достопримечательностей (i < j) с максимальной совместной ценностью по формуле:

Идея 💡

Основная задача заключается в оптимизации вычислений. Если переписать формулу как:
score = (values[i] + i) + (values[j] − j),
то видно, что для эффективного решения нужно поддерживать максимум для values[j]−j во время итерации.
Это позволяет избежать вложенных циклов и сократить сложность до O(n).

Детали подхода 🛠️

  1. Используем обратный обход массива с помощью .enumerate().rev().
  2. На каждой итерации:
    • Вычисляем текущую наилучшую ценность: score = values[i] + i + max_right,

Читать дальше →

ответить
3

Ссылка на задачу — 2226. Maximum Candies Allocated to K Children.

📌 Описание задачи

Дан массив candies, где candies[i] — это количество конфет в i-й куче. Нужно раздать конфеты k детям так, чтобы каждый ребёнок получил одинаковое количество конфет и все конфеты одного ребёнка были взяты из одной кучи.
Требуется найти максимальное возможное количество конфет, которое может получить каждый ребёнок.

💡 Идея

Перебор всех возможных вариантов распределения неэффективен. Вместо этого воспользуемся бинарным поиском по ответу:

Будем проверять, можно ли выдать каждому ребёнку candies_per_child конфет.
Если да, увеличиваем candies_per_child, иначе уменьшаем.

🛠 Подробности метода

  1. Вычисляем total_candies — суммарное количество конфет.
  2. Условие быстрого выхода: если total_candies < k, сразу возвращаем 0.
  3. Определяем предикат can_share, который проверяет, можно ли распределить candies_per_child конфет на k детей.

Читать дальше →

ответить
3

Ссылка на задачу — 2115. Find All Possible Recipes from Given Supplies.
В этой задаче для эффективного решения важно не только выбрать эффективный алгоритм, но и аккуратно разложить строки по необходимым структурам данных, избежать лишних копирований и обеспечить ясную картину ownership'a за объектами.

📌 Описание задачи

💡 Идея

Используем рекурсивный DFS для проверки доступности рецептов.
Чтобы избежать повторных вычислений, применяем мемоизацию (кеширование уже проверенных результатов).

Вместо хранения графа явным образом, мы используем индексирование рецептов и проходим по их списку ингредиентов.

🔍 Детали подхода

  1. Предобработка входных данных:
    • Создаём хеш-таблицу для быстрого доступа к индексу каждого рецепта.
    • Добавляем начальные запасы в кеш доступных ингредиентов.

Читать дальше →

ответить
3

Очередная задача — 2375. Construct Smallest Number From DI String сходу выглядит переборной, но может быть эффективно реализована за счёт использования графовых алгоритмов.

📝 Описание задачи

Дан строковый шаблон pattern, состоящий из символов I и D.
Необходимо построить лексикографически наименьшее число длины n+1, используя цифры от 1 до 9 без повторений, которое соответствует следующим требованиям:

💡 Идея

Рассмотрим шаблон как ориентированный граф, где каждая позиция (i) — это вершина.

После построения графа можно выполнить топологическую сортировку, начиная с вершин с нулевой степенью захода.
Чтобы гарантировать лексикографически наименьший порядок, обрабатываем вершины через приоритетную очередь (Min-Heap).

⚙️ Детали подхода

Читать дальше →

ответить
3

Ссылка на задачу — 3394. Check if Grid can be Cut into Sections.

📌 Описание задачи

Дано квадратное поле n×n, в котором размещены непересекающиеся прямоугольники.
Необходимо определить, можно ли сделать две горизонтальные или две вертикальные разрезки, чтобы:

Если такие разрезки возможны, вернуть true, иначе — false.

Пример

💡 Идея

Поскольку прямоугольники не пересекаются, возможные разрезки должны полностью разделять их на независимые группы.
Мы спроектируем прямоугольники на каждую ось. Если полученные отрезки отсортировать по координатам и просканировать их, можно определить количество неперекрывающихся сегментов, это позволит понять, возможно ли корректное разбиение.

Читать дальше →

ответить
3

Ссылка на задачу — 2594. Minimum Time to Repair Cars.

❓ Описание задачи

Дано:

Нужно найти минимальное время, за которое все машины будут отремонтированы.
Предполагается, что все механики работают одновременно.

💡 Идея

Механики с меньшим рангом работают быстрее.
Произведём первичное распределение машин, используя обратный квадратный корень ранга как вес, определяющий долю машин, переданных каждому механику.

Однако это распределение не покрывает все машины. Для распределения оставшихся машин мы посчитаем для каждого механика оценку времени его работы, если взять несколько дополнительных машин (тем больше, чем больше вес механика). После остаётся лишь выбрать k-ое минимальное значение среди посчитанных времён с помощью алгоритма «QuickSelect» (любезно реализованного в стандартной библиотеке Rust).

🔍 Детали подхода

1️⃣ Быстрое распределение — вычисляем вес каждого механика и распределяем машины пропорционально.

Читать дальше →

ответить
3

Задача на сегодня 2381. Shifting Letters II - решается несложно, но используемая идея мне лично кажется интересной и симпатичной.

Описание задачи 🔎

Дана строка s и список операций shifts, где каждая операция задаёт начало и конец диапазона, а также направление (вперёд или назад).
Ваша задача — применить все сдвиги к строке и вернуть окончательный результат.

Идея 🔄

Для оптимизации решения и избежания повторных расчётов сдвигов, мы используем алгоритм, основанный на префиксных суммах. Это позволяет эффективно сохранять кумулятивный эффект от всех сдвигов в отдельном массиве и применять их конечному результату за один проход.

Детали решения 📝

  1. Создадим массив net_shifts, где будут храниться чистые значения сдвигов для каждой позиции в строке.
  2. Пройдемся по всем операциям и обновим массив net_shifts, добавляя значения в начале диапазона и вычитая их сразу после его окончания.
  3. Произведем один последовательный проход по строке, вычисляя кумулятивные сдвиги и применяя их для каждого символа.

Асимптотика ⏳

Читать дальше →

ответить
3

Новая задача - 689. Maximum Sum of 3 Non-Overlapping Subarrays.

Описание задачи 📜

Дано: массив чисел nums и целое число k.
Задача: найти три непересекающихся подмассива длины k с максимальной суммой и вернуть индексы их начала.
Если существует несколько решений, вернуть лексикографически минимальное.

Идея 💡

Для нахождения оптимального решения нам нужно:

Это позволяет эффективно комбинировать результаты и найти оптимальное выделение трёх подмассива.

Детали подхода 🛠️

  1. Скользящее окно для вычисления сумм:
    • Вычисляем суммы всех подмассивов длины k, чтобы избежать повторных расчетов.
  2. Поиск лучших правых подмассивов:
    • Сканируем массив справа налево, чтобы сохранить индексы подмассивов с максимальной суммой для каждого положения.

Читать дальше →

ответить
3

Ссылка на задачу – 2342. Max Sum of a Pair With Equal Sum of Digits

📌 Условие задачи

Дан массив положительных чисел nums. Необходимо найти максимальную сумму двух различных элементов, у которых одинаковая сумма цифр. Если таких пар нет — вернуть -1.

💡 Идея решения

Вместо хранения всех чисел с одинаковой суммой цифр, достаточно хранить только максимальное из них.
Таким образом, при встрече нового числа с такой же суммой цифр можно сразу проверять, образует ли оно лучшую пару.

🔍 Подход к решению

  1. Используем массив max_per_dsum, в котором храним наибольшее число для каждой суммы цифр.
    • Максимальная сумма цифр для i32 — 82, но мы ограничиваем массив сотней для простоты.
  2. Обрабатываем nums за один проход, применяя функциональный стиль с filter_map:
    • вычисляем сумму цифр d_sum для числа n;
    • если уже есть число с таким d_sum, определяем текущую сумму пары и сохраняем обновлённое максимальное число;
    • если это первое число с данным d_sum, просто сохраняем его в max_per_dsum;
    • filter_map отбрасывает неопределённые суммы пар (None), оставляя только валидные.

Читать дальше →

ответить
3

Ссылка на задачу — 1028. Recover a Tree From Preorder Traversal.

📝 Описание задачи

Дано строковое представление бинарного дерева, полученное в порядке прямого обхода, где:

Например для следующего дерева, представление будет таким: 1-2--3---4-5--6---7

Необходимо восстановить бинарное дерево по этой строке и вернуть его корень.

💡 Идея

Читать дальше →

ответить
3

Продолжаем череду задач на перебор - 1079. Letter Tile Possibilities.

📜 Описание задачи

У нас есть набор плиток, на каждой из которых напечатана одна буква, представленный в виде строки.
Необходимо подсчитать количество различных возможных непустых последовательностей букв, которые можно составить, используя плитки.

💡 Идея решения

🧑‍💻 Подробности подхода

  1. Сортировка плиток:
    • Плитки сортируются для того, чтобы одинаковые плитки оказались рядом. Это позволяет нам эффективно группировать их в сегменты.
  2. Группировка плиток:
    • Создаем массив сегментов, где каждый элемент представляет собой количество одинаковых плиток.
    • Например, для строки "AAB" сегменты будут равны [2, 1] (2 плитки "A" и 1 плитка "B").
  3. Бэктрекинг — для каждого сегмента мы:
    • пытаемся использовать плитку (уменьшаем количество плиток в этом сегменте);

Читать дальше →

ответить
3

Следующая наша задача - 2559. Count Vowel Strings in Ranges.

📝 Описание задачи

Нам дан массив строк words и массив запросов queries, где каждый запрос задаётся парой [li, ri]. Необходимо для каждого запроса определить количество строк из диапазона [li, ri], которые начинаются и заканчиваются на гласные буквы ('a', 'e', 'i', 'o', 'u').
Вернуть массив ответов, где каждый элемент соответствует результату очередного запроса.

💡 Идея

Чтобы эффективно отвечать на диапазонные запросы, мы можем заранее подсчитать кумулятивные суммы валидных строк (начинающихся и заканчивающихся на гласные) в массиве префиксных сумм. Это позволяет сократить обработку каждого запроса до константного времени.

🔍 Подробности подхода

  1. Создание префиксных сумм:
    • Сначала создаём итератор prefix_sum_iter, вычисляющий кумулятивное количество "валидных" строк
      (неплохой повод воспользоваться для этого методом std::iter::scan).
    • Добавляем 0 в начало итогового массива (см. std::iter::once и std::iter::chain), чтобы упростить расчёты для запросов (исключая лишнюю проверку условий для обработки начала диапазона).

Читать дальше →

ответить
3

Ссылка на задачу – 1261. Find Elements in a Contaminated Binary Tree.

📝 Описание задачи

Дано двоичное дерево, в котором:

Значения всех узлов загрязнены (-1).
Нужно реализовать структуру FindElements, которая:

💡 Идея

Восстанавливать дерево не требуется!
Вместо этого мы вычисляем путь к узлу target, определяя его родителя и положение.

🔍 Детали подхода

  1. Поиск родителя (parent):

Читать дальше →

ответить
3

В очередной задаче для обзора - 802. Find Eventual Safe States нам предстоит найти вершины, не попадающие в циклы графа.

📋 Описание задачи

Нужно определить безопасные вершины в ориентированном графе.

💡 Идея

Задача решается с помощью обхода графа в глубину (DFS) и вектора состояний.
Каждому узлу присваивается одно из трёх состояний:

  1. Unseen (ещё не обработан);
  2. Processing (в процессе обработки; узлы, являющиеся частью цикла, остаются в этом состоянии и после обработки);
  3. Safe (безопасный).

🔍 Детальное описание подхода

Читать дальше →

ответить
3

Ссылка на задачу – 1910. Remove All Occurrences of a Substring.

📌 Описание задачи

Даны две строки s и part. Нужно избавиться от всех вхождений part из s, выполняя следующую операцию:

🐢 Анализ наивного решения

Достаточно несложно быстро набросать следующее решение:

impl Solution {
    pub fn remove_occurrences(mut s: String, part: String) -> String {
        let P = part.len();
        while let Some(idx) = s.find(&part) {
            s.replace_range(idx..idx+P, "");
        }
        s
    }
}

Читать дальше →

1 ответ
3

Задача: 2940. Find Building Where Alice and Bob Can Meet

Описание задачи 📝

У нас есть массив heights, где heights[i] представляет высоту здания i.
Также даны запросы в виде массива queries, где каждый запрос [ai,bi>] требует определить самое левое здание, на которое могут попасть Алиса и Боб, начав с ai​ и bi​ соответственно, при соблюдении следующих условий:

Если подходящее здание невозможно найти, результат для данного запроса равен −1.

Идея 💡

Мне сходу не известна эффективная структура данных для онлайн-разрешения запросов.
Но можно поступить хитрее, а именно:

Читать дальше →

ответить

Страница 1 2 3 4