题目
给你一个数组 prices
,其中 prices[i]
是商店里第 i
件商品的价格。
商店里正在进行促销活动,如果你要买第 i
件商品,那么你可以得到与 prices[j]
相等的折扣,其中 j
是满足 j > i
且 prices[j] <= prices[i]
的 最小下标 ,如果没有满足条件的 j
,你将没有任何折扣。
请你返回一个数组,数组中第 i
个元素是折扣后你购买商品 i
最终需要支付的价格。
示例 1:
输入:prices = [8,4,6,2,3] 输出:[4,2,4,2,3] 解释: 商品 0 的价格为 price[0]=8 ,你将得到 prices[1]=4 的折扣,所以最终价格为 8 - 4 = 4 。 商品 1 的价格为 price[1]=4 ,你将得到 prices[3]=2 的折扣,所以最终价格为 4 - 2 = 2 。 商品 2 的价格为 price[2]=6 ,你将得到 prices[3]=2 的折扣,所以最终价格为 6 - 2 = 4 。 商品 3 和 4 都没有折扣。
示例 2:
输入:prices = [1,2,3,4,5] 输出:[1,2,3,4,5] 解释:在这个例子中,所有商品都没有折扣。
示例 3:
输入:prices = [10,1,1,6] 输出:[9,0,1,6]
提示:
1 <= prices.length <= 500
1 <= prices[i] <= 10^3
提交代码
//商品折扣后的最终价格
//单调栈
//j商品在i商品的右边
//j商品是i商品右边的第一个价格小于i商品的商品->找下一个更小的元素
//如果没有满足条件的 j,将没有任何折扣。
//求各个商品最终支付的价格
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
vector<int> prices;//各个商品价格
int n;//商品数量
stack<int> stk;//单调栈,存储的是商品价格
vector<int> result;//存储结果
//确认商品最终价格
void fp(int i){
int discount = 0;//折扣初始化为0
//找“商品j”
while(!stk.empty()){
if(prices[i] < stk.top()){
//比商品i大
stk.pop();
}else{
discount = stk.top();
break;
}
}
result.push_back(prices[i] - discount);
stk.push(prices[i]);
}
int main(){
//输入商品价钱
int p;//存储商品价钱
while(cin.peek() != '\n'){
scanf("%d",&p);
prices.push_back(p);
}
//-------------------------------
n = prices.size();//商品数量
//从右向左找
for(int i = n - 1;i >= 0;i--){
fp(i);
}
reverse(result.begin(),result.end());
//输出结果
for(int i = 0;i < n;i++){
printf("%d ",result[i]);
}
return 0;
}
总结
主要思路:单调栈。
注意单调栈的单调性究竟是单调递增还是单调递减的,要让单调栈的循环判断有意义。如,要找下一个更小的元素,则单调栈从栈顶到栈底应该是递减的才有意义,栈顶一直是离得最近的,往后依次变小,没有必要依次变大。
reverse()方法使用需要#include<algorithm>;