главная новое лучшее написать
2

Ссылка на задачу — 2780. Minimum Index of a Valid Split.

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

💡 Идея

Для эффективного поиска доминирующего элемента хорошо подходит алгоритм большинства голосов Бойера — Мура.
Зная доминирующий элемент, можно пройти по массиву и в каждой возможной точке разделения отслеживать:

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

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

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

ответить
2

Ссылка на задачу — 2033. Minimum Operations to Make a Uni-Value Grid.

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

Дан двумерный массив grid размером m x n, а также число x.
За одну операцию можно прибавить или

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

ответить
3

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

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

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

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

Пример

💡 Идея

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

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

ответить
3

Ссылка на задачу — 3169. Count Days Without Meetings.

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

Нужно посчитать количество дней, когда сотрудник свободен от встреч и может работать.

💡 Идея

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

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

1️⃣ Сортируем встречи по начальной дате.
2️⃣ Проходим по списку встреч, отслеживая next_free (следующий свободный день).
3️⃣ Подсчитываем разрывы между next_free и началом следующей встречи.
4️⃣ Обновляем next_free после каждой встречи, сдвигая его на день после её окончания.
5️⃣ Добавляем свободные дни после последней встречи.

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

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

impl Solution {
    pub fn count_days(days: i32, mut meetings: Vec<Vec<i32>>) -> i32 {
        meetings.sort_unstable_by_key(|meet| meet[0]);

        let (next_free, free_count) = meetings.into_iter()
            .fold((1, 0), |(next_free, free_count), meet| {
                let [start, end] = meet[..2] else { unreachable!("bad meet format") };
                let gap = (start - next_free).max(0);
                let next_free = next_free.max(end + 1);
                (next_free, free_count + gap)
        });

        free_count + (days - next_free + 1).max(0)
    }
}

Tags: #rust #algorithms #counting

ответить
3

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

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

💡 Идея

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

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

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

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

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

ответить
3

Ссылка на задачу — 3108. Minimum Cost Walk in Weighted Graph.

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

Пример

💡 Идея

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

1 ответ
3

Ссылка на задачу — 2401. Longest Nice Subarray.

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

Дан массив nums, состоящий из целых чисел.
Нужно найти наибольший подмассив, в котором ни одна пара чисел не имеет общих установленных битов
(т.е. их побитовое И (&) равно 0).

Пример

💡 Идея

Будем решать задачу в чистом функциональном стиле, используя технику скользящего окна.

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

1 ответ
2

Ссылка на задачу — 3191. Minimum Operations to Make Binary Array Elements Equal to One I.

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

Пример:

💡 Идея

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

ответить
3

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

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

Дано:

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

💡 Идея

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

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

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

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

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

ответить
3

Ссылка на задачу — 3480. Maximize Subarrays After Removing One Conflicting Pair.

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

Пример

💡 Идея

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

ответить
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

Ссылка на задачу — 3356. Zero Array Transformation II.

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

Дан массив nums длины N и список запросов queries, каждый из которых задаётся как [li, ri, vali]. Запрос означает, что значения в диапазоне [li, ri] можно уменьшить на любое число от 0 до vali независимо друг от друга.

Нужно найти минимальное число первых запросов k, после которых nums может превратится в массив, состоящий только из нулей. Если это невозможно — вернуть -1.

💡 Идея

Вместо того, чтобы изменять nums напрямую, будем хранить массив последовательных изменений к декременту (updates). Он позволяет эффективно применять диапазонные операции без лишних вычислений.

Чтобы минимизировать количество обработанных запросов, будем использовать жадную стратегию обработки запросов:

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

  1. Используем массив updates (N+1 элементов), где updates[i] хранит последовательные изменения к декременту значений.

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

ответить
3

Ссылка на задачу — 3479. Fruits Into Baskets III.

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

У нас есть два массива:

Нужно распределить фрукты по корзинам слева направо по следующим правилам:

Требуется вернуть количество неразмещённых фруктов.

💡 Идея

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

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

  1. Построение дерева отрезков 🌳:
    • Создаём дерево отрезков для максимумов на интервалах, инициализируюя его вместимостями корзин.

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

ответить
3

Ссылка на задачу — 3306. Count of Substrings Containing Every Vowel and K Consonants II.

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

Дана строка word и неотрицательное число k.
Необходимо подсчитать количество подстрок, в которых встречаются все гласные буквы ('a', 'e', 'i', 'o', 'u') хотя бы по одному разу и ровно k согласных.

💡 Идея

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

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

  1. Для каждой гласной буквы сохраняется её последняя позиция.
  2. Для согласных используется итератор, последовательно предоставляющий позиции согласных в строке.
  3. Если количество согласных становится больше k, левая граница окна перемещается вперёд.
  4. При каждом совпадении условий (ровно k согласных и присутствуют все гласные) подсчитывается количество допустимых подстрок.

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

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

ответить
3

Ссылка на задачу — 2379. Minimum Recolors to Get K Consecutive Black Blocks.

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

Дана строка blocks, состоящая из символов 'W' (белый) и 'B' (чёрный).
Необходимо определить минимальное число перекрашиваний белых блоков в чёрные, чтобы получить хотя бы одну последовательность из k подряд идущих чёрных блоков.

💡 Идея

Используем технику скользящего окна:

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

  1. Посчитаем число белых блоков в первом окне размера k.
  2. Сдвигаем окно вправо на один символ за раз:
    • если символ, который «входит» в окно, белый ('W'), увеличиваем счётчик;
    • если символ, который «выходит» из окна, белый, уменьшаем счётчик.
  3. После каждого сдвига окна обновляем минимальное найденное значение.
  4. Итоговый ответ — это минимальное число белых блоков за всё время обхода.

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

🛠️ Исходный код

impl Solution {
    pub fn minimum_recolors(blocks: String, k: i32) -> i32 {
        let blocks = blocks.as_bytes();
        let k = k as usize;

        // Count white blocks ('W') in the first window of size k
        let initial_recolors = blocks[..k].iter().filter(|&&b| b == b'W').count() as i32;

        // Slide window over the blocks using iterator methods
        blocks
            .windows(k+1)
            .fold((initial_recolors, initial_recolors), |(current, min), window| {
                // Update recolors based on outgoing and incoming blocks
                let next = current 
                    + (window.last() == Some(&b'W')) as i32 
                    - (window.first() == Some(&b'W')) as i32;

                (next, min.min(next))
            }).1
    }
}

Tags: #rust #algorithms #counting

ответить
3

Очередная наша задача — 2579. Count Total Number of Colored Cells, как ни странно, красиво решается на шахматной доске ☺.

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

Дана бесконечная двумерная сетка с неокрашенными клетками. В течение n минут выполняются следующие действия:

Необходимо вычислить количество окрашенных клеток после n минут.

🧠 Идея

Если рассмотреть процесс закрашивания клеток на шахматной доске, можно увидеть, что в момент n окрашенные клетки образуют два наложенных квадрата:

Сумма площадей этих двух квадратов и дает общее количество окрашенных клеток.

chess-pattern-s.png

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

Применяем формулу: Total = n²+(n−1)²

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

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

impl Solution {
    pub fn colored_cells(n: i32) -> i64 {
        let n = n as i64;
        n*n + (n-1)*(n-1)
    }
}

Tags: #rust #algorithms #math

ответить
3

Ссылка на задачу - 1780. Check if Number is a Sum of Powers of Three.

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

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

🔹 Пример:

💡 Идея

Рассмотрим представление n в троичной системе счисления:

Таким образом, задача сводится к поразрядной проверке числа в троичной системе счисления.

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

Будем использовать рекурсию и деление числа на 3:

  1. База рекурсии: Если n == 0, то мы успешно разложили число, возвращаем true.
  2. Шаг рекурсии: Если n % 3 == 2, то n нельзя разложить, возвращаем false.
  3. Рекурсивный вызов: Проверяем n / 3, повторяя процесс.

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

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

impl Solution {
    pub fn check_powers_of_three(n: i32) -> bool {
        n == 0 || (n % 3 != 2 && Self::check_powers_of_three(n / 3))
    }
}

Tags: #rust #algorithms #math

ответить
3

Ссылка на задачу - 2161. Partition Array According to Given Pivot.
В данной задаче нам предстоит реализовать базовую подзадачу Быстрой сортировки, но с дополнительным требованием сохранения относительного порядка, отчего стандартные методы реализации Q-sort нас не будут устраивать ☹

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

Дан массив nums и число pivot. Требуется переставить элементы массива так, чтобы:

💡 Идея

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

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

1️⃣ Первый проход: добавляем в результат все элементы < pivot.
2️⃣ Подсчет и второй проход: вычисляем количество вхождений pivot в массиве и добавляем pivot в результат pivot_count раз.
3️⃣ Третий проход: добавляем все элементы > pivot в результат.

Используем Vec::with_capacity(nums.len()), чтобы избежать лишних аллокаций.

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

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

impl Solution {
    pub fn pivot_array(nums: Vec<i32>, pivot: i32) -> Vec<i32> {
        let mut result = Vec::with_capacity(nums.len());

        // First pass: Collect elements smaller than pivot
        result.extend(nums.iter().filter(|&&num| num < pivot));

        // Count occurrences of pivot
        let pivot_count = nums.iter().filter(|&&num| num == pivot).count();

        // Insert pivot elements
        result.extend(std::iter::repeat(pivot).take(pivot_count));

        // Third pass: Collect elements greater than pivot using into_iter() to take ownership
        result.extend(nums.into_iter().filter(|&num| num > pivot));

        result
    }
}

Tags: #rust #algorithms

1 ответ
3

Ссылка на задачу - 2570. Merge Two 2D Arrays by Summing Values.

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

Даны два отсортированных списка nums1 и nums2, где каждый элемент представлен в виде [id, value].
Нужно объединить их в один список, упорядоченный по id, при этом суммируя значения для совпадающих id.

💡 Идея

Так как оба списка уже отсортированы по id, можно пройтись по ним одновременно, сравнивая id и добавляя элементы в результат.
Такой метод позволяет решить задачу за O(n + m) без дополнительной сортировки.

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

  1. Используем два индекса i и j для итерации по nums1 и nums2.
  2. Сравниваем текущие id:
    • Если id1 < id2 → добавляем nums1[i] в результат, сдвигаем i.
    • Если id1 > id2 → добавляем nums2[j] в результат, сдвигаем j.
    • Если id1 == id2 → суммируем значения, добавляем результат, сдвигаем оба указателя.
  3. Добавляем оставшиеся элементы из nums1 и nums2, если таковые имеются.

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

ответить
2

Ссылка на задачу — 2523. Closest Prime Numbers in Range.

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

Нам даны два целых числа left и right.
Нужно найти два ближайших простых числа num1 и num2 таких, что:

Если существует несколько пар с одинаковой разницей, выбрать пару с меньшим первым числом.
Если таких чисел нет, вернуть [-1, -1].

🧠 Идея

Будем просто итерироваться по парам соседних простых чисел в заданом диапазоне.
Но, так как простые близнецы (пары простых чисел, разница между которыми равна 2) встречаются довольно часто (их плотность примерно 1 / log²(n)) мы можем эффективно ввести условие раннего выхода, которое значительно улучшает среднюю производительность алгоритма.

🔍 Подход

  1. Обработка граничных случаев:
    • Если left ≤ 2 и right ≥ 3, сразу возвращаем [2, 3].
  2. Перебор чисел в диапазоне:
    • Проверяем каждое число на простоту с помощью is_prime(n), работающей за O(√n).

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

ответить
3

Ссылка на задачу — 2460. Apply Operations to an Array.

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

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

💡 Идея

Решение можно выполнить за один проход, используя два указателя (read и write):

Такой подход позволяет изменять массив на месте, не используя дополнительную память.

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

  1. Используем два указателя (read и write):
    • read проходит по массиву.
    • write отслеживает следующую позицию для ненулевых чисел.

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

ответить
2

Ссылка на задачу — 2965. Find Missing and Repeated Values.

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

Дан n×n целочисленный массив grid, содержащий числа от 1 до .
Одно число повторяется дважды (a), а одно отсутствует (b).
Нужно найти их.

💡 Идея

Мы можем использовать математические свойства сумм чисел:

Разница между ожидаемыми и фактическими значениями позволит выразить a и b через систему уравнений.

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

  1. Вычисляем ожидаемую сумму и ожидаемую сумму квадратов для чисел от 1 до .
  2. Проходим по grid, вычисляя фактическую сумму и фактическую сумму квадратов.
  3. Находим промежуточные величины для системы уравнений:
    • (a - b) = sum_diff

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

ответить
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

Ссылка на задачу — 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

Ссылка на задачу — 2467. Most Profitable Path in a Tree.

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

Дано неориентированное корневое дерево с n узлами (нумерованными от 0 до n-1).

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

💭 Идея

Вместо раздельного запуска BFS для поиска пути Боба и последующего прохода динамического программирования по узлам дерева, мы решим задачу одним рекурсивным DFS-проходом.

Для каждого узла будем вычислять:

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

ответить

Страница 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18