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

Сегодняшняя задача 1475. Final Prices With a Special Discount in a Shop решается с помощью стандартного стека, но интересно и нестандартно выглядит мотивация его использования.

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

У вас есть массив цен prices, где prices[i] — это цена i-го товара. Если вы покупаете товар i, вы можете получить скидку, равную цене первого товара с индексом j>i, для которого выполняется условие prices[j] ≤ prices[i]. Если такого товара нет, скидка не применяется. Требуется вернуть массив, где каждая позиция показывает финальную цену с учётом скидки.

Идея 🤔

Подход 🚀

  1. Создаём стек discount_candidates, чтобы хранить индексы товаров, ожидающих применения скидки.
  2. Итерируем по массиву prices:
    • Пока верхний элемент стека соответствует условию скидки (цена товара в стеке ≥ текущей цене), применяем скидку и удаляем элемент из стека.
    • Добавляем текущий индекс в стек.
  3. Возвращаем обновлённый массив цен.

Сложность 📊

Исходный код решения

impl Solution {
    pub fn final_prices(prices: Vec<i32>) -> Vec<i32> {
        let mut result = prices.clone(); // Clone prices to modify and return
        let mut discount_candidates: Vec<usize> = Vec::new(); // Stack to store indices of items awaiting discounts

        for (idx, price) in prices.into_iter().enumerate() {
            // Process the stack to apply discounts where applicable
            while let Some(&largest_candidate_index) = discount_candidates.last() {
                if result[largest_candidate_index] >= price {
                    result[largest_candidate_index] -= price; // Apply the discount
                    discount_candidates.pop(); // Remove from stack
                } else {
                    break; // Stop if the discount condition is not met
                }
            }
            // Add the current index to the stack for future discounts
            discount_candidates.push(idx);
        }

        result
    }
}

Замечания

Если вчитаться в ограничения задачи на LeetCode - то заходить должно решение и за O(N³) (что уже больше сложности наивного подхода). Но этот быстрый алгоритм получился достаточно симпатичным на мой взгляд, чтобы интересно было им поделиться :)