
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:
- 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.
- The first item is $8, and the closest subsequent item that is less or equal is $4 (
For strictly ascending arrays like
prices = [1,2,3,4,5]
, no discounts are applicable as there's noj
such thatprices[j]
<=prices[i]
for eachi
.For an array like
prices = [10,1,1,6]
, even multiple sequential smaller or equal values yield a discount calculation by finding the nearest validj
.
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
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 indiscountedPrices
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.
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:
- Clone the original
costs
array todiscountedCosts
which will store the final prices after discounts are applied. - Initialize a
Stack
(indexStack
) that will hold indexes of the prices. - Iterate through each price in the
costs
array using a for loop. - 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.
- Push the current index onto the stack to track it for potential future discounts.
- 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.
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 indiscountedPrices
. - 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.
No comments yet.