对于第 i 件商品的价格为 prices}[i],我们需要查找到相应可能的折扣。按照题目要求,我们从第 i + 1 件商品开始依次向后遍历,直到找到第一个满足 prices}[j] \le \textit{prices}[i] 的下标 j 即可求出该物品的最终折扣价格。我们按照题目要求依次遍历即可。
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: deffinalPrices(self, prices: List[int]) -> List[int]: n = len(prices) ans = [0] * n for i, p inenumerate(prices): discount = 0 for j inrange(i + 1, n): if prices[j] <= p: discount = prices[j] break ans[i] = p - discount return ans
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution { public: vector<int> finalPrices(vector<int>& prices){ int n = prices.size(); vector<int> ans; for (int i = 0; i < n; ++i) { int discount = 0; for (int j = i + 1; j < n; ++j) { if(prices[j] <= prices[i]){ discount = prices[j]; break; } } ans.emplace_back(prices[i] - discount); } return ans; } };
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { publicint[] finalPrices(int[] prices) { intn= prices.length; int[] ans = newint[n]; for (inti=0; i < n; ++i) { intdiscount=0; for (intj= i + 1; j < n; ++j) { if(prices[j] <= prices[i]){ discount = prices[j]; break; } } ans[i] = prices[i] - discount; } return ans; } }
[sol1-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicclassSolution { publicint[] FinalPrices(int[] prices) { int n = prices.Length; int[] ans = newint[n]; for (int i = 0; i < n; ++i) { int discount = 0; for (int j = i + 1; j < n; ++j) { if(prices[j] <= prices[i]){ discount = prices[j]; break; } } ans[i] = prices[i] - discount; } return ans; } }
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int* finalPrices(int* prices, int pricesSize, int* returnSize) { int *ans = (int *)malloc(sizeof(int) * pricesSize); for (int i = 0; i < pricesSize; ++i) { int discount = 0; for (int j = i + 1; j < pricesSize; ++j) { if(prices[j] <= prices[i]){ discount = prices[j]; break; } } ans[i] = prices[i] - discount; } *returnSize = pricesSize; return ans; }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var finalPrices = function(prices) { const n = prices.length; const ans = newArray(n).fill(0); for (let i = 0; i < n; ++i) { let discount = 0; for (let j = i + 1; j < n; ++j) { if(prices[j] <= prices[i]){ discount = prices[j]; break; } } ans[i] = prices[i] - discount; } return ans; };
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcfinalPrices(prices []int) []int { ans := make([]int, len(prices)) for i, p := range prices { discount := 0 for _, q := range prices[i+1:] { if q <= p { discount = q break } } ans[i] = p - discount } return ans }
复杂度分析
时间复杂度:O(n ^ 2),其中 n 为数组的长度。对于每个商品,我们需要遍历一遍数组查找符合题目要求的折扣。
空间复杂度:O(1)。返回值不计入空间复杂度。
方法二:单调栈
本题可以采用「单调栈 」的解法,可以参考「496. 下一个更大元素 I 的官方题解 」。使用单调栈先预处理 prices,使得查询 prices 中每个元素对应位置的右边的第一个更小的元素值时不需要再遍历 prices。解法的重点在于考虑如何更高效地计算 prices 中每个元素右边第一个更小的值。倒序遍历 prices,并用单调栈中维护当前位置右边的更小的元素列表,从栈底到栈顶的元素是单调递增的。具体每次我们移动到数组中一个新的位置 i,就将单调栈中所有大于 prices}[i] 的元素弹出单调栈,当前位置右边的第一个小于等于 prices}[i] 的元素即为栈顶元素,如果栈为空则说明当前位置右边没有更大的元素,随后我们将位置 i 的元素入栈。
如果当前栈顶的元素小于等于 prices}[i],此时可以知道当前栈顶元素即为 i 的右边第一个小于等于 prices}[i] 的元素,此时第 i 个物品折后的价格为 prices}[i] 与栈顶的元素的差。
如果当前栈中的元素为空,则此时折扣为 0,商品的价格为原价 prices}[i];
将 prices}[i] 压入栈中,保证 prices}[i] 为当前栈中的最大值;
[sol2-Python3]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: deffinalPrices(self, prices: List[int]) -> List[int]: n = len(prices) ans = [0] * n st = [0] for i inrange(n - 1, -1, -1): p = prices[i] whilelen(st) > 1and st[-1] > p: st.pop() ans[i] = p - st[-1] st.append(p) return ans
[sol2-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution { public: vector<int> finalPrices(vector<int>& prices){ int n = prices.size(); vector<int> ans(n); stack<int> st; for (int i = n - 1; i >= 0; i--) { while (!st.empty() && st.top() > prices[i]) { st.pop(); } ans[i] = st.empty() ? prices[i] : prices[i] - st.top(); st.emplace(prices[i]); } return ans; } };
[sol2-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { publicint[] finalPrices(int[] prices) { intn= prices.length; int[] ans = newint[n]; Deque<Integer> stack = newArrayDeque<Integer>(); for (inti= n - 1; i >= 0; i--) { while (!stack.isEmpty() && stack.peek() > prices[i]) { stack.pop(); } ans[i] = stack.isEmpty() ? prices[i] : prices[i] - stack.peek(); stack.push(prices[i]); } return ans; } }
[sol2-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicclassSolution { publicint[] FinalPrices(int[] prices) { int n = prices.Length; int[] ans = newint[n]; Stack<int> stack = new Stack<int>(); for (int i = n - 1; i >= 0; i--) { while (stack.Count > 0 && stack.Peek() > prices[i]) { stack.Pop(); } ans[i] = stack.Count == 0 ? prices[i] : prices[i] - stack.Peek(); stack.Push(prices[i]); } return ans; } }
[sol2-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int* finalPrices(int* prices, int pricesSize, int* returnSize) { int *ans = (int *)malloc(sizeof(int) * pricesSize); int *stack = (int *)malloc(sizeof(int) * pricesSize); int top = 0; for (int i = pricesSize - 1; i >= 0; i--) { while (top > 0 && stack[top - 1] > prices[i]) { top--; } ans[i] = top == 0 ? prices[i] : prices[i] - stack[top - 1]; stack[top++] = prices[i]; } *returnSize = pricesSize; free(stack); return ans; }
[sol2-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13
var finalPrices = function(prices) { const n = prices.length; const ans = newArray(n).fill(0); const stack = []; for (let i = n - 1; i >= 0; i--) { while (stack.length && stack[stack.length - 1] > prices[i]) { stack.pop(); } ans[i] = stack.length === 0 ? prices[i] : prices[i] - stack[stack.length - 1]; stack.push(prices[i]); } return ans; };
[sol2-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcfinalPrices(prices []int) []int { n := len(prices) ans := make([]int, n) st := []int{0} for i := n - 1; i >= 0; i-- { p := prices[i] forlen(st) > 1 && st[len(st)-1] > p { st = st[:len(st)-1] } ans[i] = p - st[len(st)-1] st = append(st, p) } return ans }