class Solution:
def finalPrices(self, prices):
n = len(prices)
answer = prices[:]
for i in range(n):
for j in range(i+1, n):
if prices[j] <= prices[i]:
answer[i] = prices[i] - prices[j]
break
return answer
class Solution {
public:
vector<int> finalPrices(vector<int>& prices) {
int n = prices.size();
vector<int> answer = prices;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (prices[j] <= prices[i]) {
answer[i] = prices[i] - prices[j];
break;
}
}
}
return answer;
}
};
class Solution {
public int[] finalPrices(int[] prices) {
int n = prices.length;
int[] answer = prices.clone();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (prices[j] <= prices[i]) {
answer[i] = prices[i] - prices[j];
break;
}
}
}
return answer;
}
}
var finalPrices = function(prices) {
let n = prices.length;
let answer = prices.slice();
for (let i = 0; i < n; ++i) {
for (let j = i + 1; j < n; ++j) {
if (prices[j] <= prices[i]) {
answer[i] = prices[i] - prices[j];
break;
}
}
}
return answer;
};
You are given an array of integers called prices
, where each element represents the price of an item in a shop, arranged in the order they are displayed. For each item at index i
, you need to find the first item with index j > i
such that prices[j] <= prices[i]
. If such an item exists, you receive a discount equal to prices[j]
on the current item. If no such item exists, there is no discount. The goal is to return an array where each element is the final price after applying the special discount described above.
Key constraints:
At first glance, the problem looks like we need to, for each item, scan ahead to find the first item that is less than or equal to its value. This suggests a straightforward brute-force approach where, for each item, we look at every item that comes after it until we find a suitable discount or reach the end of the array.
However, brute-force can be inefficient for large arrays. We might wonder if there's a way to make this more efficient, perhaps by using a stack to remember possible discounts as we scan through the list. The key insight is that for each item, we're only interested in the first qualifying price after it, which hints at a "next less than or equal" pattern, often solved with a stack.
Let's walk through both the brute-force and optimized approaches:
i
in prices
:j > i
.prices[j] <= prices[i]
, subtract prices[j]
from prices[i]
and break.j
is found, keep the original price.prices
array:prices[current]
<= prices[stack.top()]
:
prices[current]
.For teaching purposes, the initial brute-force solution is often used, as shown in the code tabs above.
Let's use the input prices = [8, 4, 6, 2, 3]
:
prices[0] = 8
):
prices[1] = 4
):
prices[2] = 6
):
prices[3] = 2
):
prices[4] = 3
):
The final output is [4, 2, 4, 2, 3]
.
The key insight is that for each price, we want the first following price that is less than or equal to it. The brute-force approach is intuitive but slow for large inputs. Using a stack, we can efficiently find and apply discounts in a single pass, making the solution both elegant and optimal. This pattern of "next less than or equal" is common and recognizing it allows us to use efficient data structures like stacks to solve similar problems quickly.