Final Prices With a Special Discount in a Shop

Updated on 27 May, 2025
Final Prices With a Special Discount in a Shop header image

Problem Statement

In this task, you are given an array prices, wherein prices[i] represents the cost of the i-th item in a store. This store offers a unique discounting method. For any given item you choose to buy, a discount will be applied based on a subsequent item's price, which is less than or equal to and closest to the current item's price. Specifically, if you choose to buy item i, the discount applied will equal the price of item j, where j is the smallest index greater than i (j > i) such that prices[j] is less than or equal to prices[i]. If no such j exists, then no discount is applied to item i.

Your objective is to compute and return an array answer, where answer[i] provides the final price for item i considering the applicable discount.

Examples

Example 1

Input:

prices = [8,4,6,2,3]

Output:

[4,2,4,2,3]

Explanation:

For item 0 with price[0]=8 you will receive a discount equivalent to prices[1]=4, therefore, the final price you will pay is 8 - 4 = 4.
For item 1 with price[1]=4 you will receive a discount equivalent to prices[3]=2, therefore, the final price you will pay is 4 - 2 = 2.
For item 2 with price[2]=6 you will receive a discount equivalent to prices[3]=2, therefore, the final price you will pay is 6 - 2 = 4.
For items 3 and 4 you will not receive any discount at all.

Example 2

Input:

prices = [1,2,3,4,5]

Output:

[1,2,3,4,5]

Explanation:

In this case, for all items, you will not receive any discount at all.

Example 3

Input:

prices = [10,1,1,6]

Output:

[9,0,1,6]

Constraints

  • 1 <= prices.length <= 500
  • 1 <= prices[i] <= 1000

Approach and Intuition

Understanding the problem involves realizing that for each item in the array, you need to look for the next item that is either of equal or less value to apply as a discount. This can be visualized as:

  1. For each item in the array:
    • Initialize the final price as the original price (since it might happen that no discount is applicable).
    • Check subsequent items to find the first item that has a price less than or equal to the current item's price.
    • If such an item is found, subtract its price from the current item's price to get the discounted price.
    • If no such item is found, the price remains unchanged.

Based on the described approach, let's look at the provided examples:

  • For prices = [8,4,6,2,3]:

    • The first item is $8, and the closest subsequent item that is less or equal is $4 (prices[1]). So, the final price is $8 - $4 = $4.
    • For the second item $4, the closest less or equal subsequent price is $2 (prices[3]), and thus $4 - $2 = $2.
    • Similarly, for the third item $6, apply a discount of $2.
    • Items that don't find any less or equal subsequent prices carry their original prices.
  • For strictly ascending arrays like prices = [1,2,3,4,5], no discounts are applicable as there's no j such that prices[j] <= prices[i] for each i.

  • For an array like prices = [10,1,1,6], even multiple sequential smaller or equal values yield a discount calculation by finding the nearest valid j.

From this analysis and examples, the behavior and results of the code can be appropriately predicted and verified with respect to given constraints and different scenarios.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    vector<int> reducedPrices(vector<int>& inputPrices) {
        vector<int> discountedPrices = inputPrices;
        stack<int> indicesStack;

        for (int index = 0; index < inputPrices.size(); index++) {
            while (!indicesStack.empty() && inputPrices[indicesStack.top()] >= inputPrices[index]) {
                discountedPrices[indicesStack.top()] -= inputPrices[index];
                indicesStack.pop();
            }
            indicesStack.push(index);
        }

        return discountedPrices;
    }
};

The provided C++ solution implements a function reducedPrices to calculate the final prices of items after applying a special discount. Each item’s discount is the price of the next item that is cheaper or equal in value and appears later in the list. If no such item exists, no discount is applied for that item.

The function takes a vector inputPrices as input, which contains the original prices of the items. It initializes discountedPrices with the original prices and uses a stack indicesStack to keep track of indices of prices that might be eligible for a discount.

Working mechanism:

  • Iterates over each price using index.
  • Checks elements in the stack; if the current price at index is less than or equal to the price at the index stored at the top of the stack, it applies the discount to the price in discountedPrices corresponding to the top of the stack and then removes the index from the stack.
  • Pushes the current index to the stack for potential future discounts.

This approach ensures each price is compared with following prices only once, hence the function operates efficiently with a time complexity essentially linear to the number of items, due to the properties of stack operations (push and pop).

At the end of the loop, discountedPrices containing all discounted prices is returned. This vector represents the final prices of items where each eligible item has been discounted based on its qualifying subsequent lower or equal priced item.

java
class Solution {

    public int[] applyDiscounts(int[] costs) {
        // Duplicate the costs array to hold the discounted values
        int[] discountedCosts = costs.clone();

        Stack<Integer> indexStack = new Stack<>();

        for (int index = 0; index < costs.length; index++) {
            // Check and apply discounts as pertinent
            while (!indexStack.isEmpty() && costs[indexStack.peek()] >= costs[index]) {
                // Deduct the discount from the applicable product
                discountedCosts[indexStack.pop()] -= costs[index];
            }
            // Track current product index
            indexStack.push(index);
        }

        return discountedCosts;
    }
}

The provided Java solution addresses the problem of applying a special discount to a list of prices in a shop. Each price can potentially be discounted based on the next lower or equal price coming after it in the list. The algorithm makes use of a stack to efficiently manage and apply these discounts.

The core functionality is implemented in the applyDiscounts method of the Solution class. Here's a breakdown of the method:

  1. Clone the original costs array to discountedCosts which will store the final prices after discounts are applied.
  2. Initialize a Stack (indexStack) that will hold indexes of the prices.
  3. Iterate through each price in the costs array using a for loop.
  4. Inside the loop, use another loop to:
    • Check if the stack is not empty and the current price is less than or equal to the price at the index on the top of the stack.
    • If the condition is true, update the price in discountedCosts at the top index of the stack by subtracting the current price (the discount).
    • Pop the index from the stack.
  5. Push the current index onto the stack to track it for potential future discounts.
  6. Return the discountedCosts array containing prices after discounts were applied.

This method efficiently computes the final prices by using stack operations that provide O(1) time complexity for push and pop operations, leading to an overall time complexity of O(n), where n is the number of items in the costs array. This approach ensures that each price is processed in a linear pass, making it optimal for this type of discount application where the next least or equal price affects the discounting of previous prices.

python
class Solution:
    def calculateDiscountedPrices(self, prices: List[int]) -> List[int]:
        # Container for discounted price calculations
        discountedPrices = prices.copy()
        
        # Use a deque to manage indices for processing discounts
        indicesStack = deque()

        for index in range(len(prices)):
            # Check possible discounts with previous kept indices
            while indicesStack and prices[indicesStack[-1]] >= prices[index]:
                # Apply available discount to the price at the popped index
                discountedPrices[indicesStack.pop()] -= prices[index]
            # Store current index to potentially use for future discounts
            indicesStack.append(index)
        
        return discountedPrices

This Python solution is designed to apply a special discount strategy to a list of prices in a shop. The function calculateDiscountedPrices efficiently computes the final prices after applying the necessary discounts. Here's how the algorithm works:

  • Start by creating a copy of the original list, discountedPrices, which will hold the final discounted values.
  • Use a deque, named indicesStack, to keep track of the indices while iterating through the price list. This helps in determining when and where discounts can be applied.
  • Iterate over the prices using a loop. For each price, the loop checks if there's a discount possibility by referencing the indices stored in indicesStack.
  • If the current price is lower than or equal to the price at the last index stored in indicesStack, it means a discount can be applied to the item represented by that stored index. The discount is the value of the current price, and it's subtracted from the corresponding price in discountedPrices.
  • After processing possible discounts for the current price, store its index in indicesStack for potential future discounts.
  • Once all indices are processed, the list discountedPrices with applied discounts is returned.

This method leverages a monotonic stack approach by handling indices in the indicesStack to keep track of potential discounts, ensuring an efficient run-time complexity.

Comments

No comments yet.