1475. 商品折扣後的最終價格
阿新 • • 發佈:2020-08-26
1475. 商品折扣後的最終價格
難度簡單給你一個數組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
單調棧最全面詳解,包你懂!
諾*^_^*言釋出於2020-06-22867C++棧Java解題思路
這裡我們考慮一個過程中的情況(這裡維護一個單調遞增的佇列,!!要將所有元素都加入一次佇列(一定記住這句話)):
>a0 a1 a2 a3 ... am ... an 單調遞增;n可以為0個(空數列,初始情況)
現在我們判斷an+1,如果an+1 <= a0 那麼a0-an的元素都需要-an+1(題幹說的第一個小於等於的元素要減去嘛;因為我們保證了a0-an是單調遞增的了(且n=1的時候就是隻有a0),所以an+1一定是第一個小於等於a0-an的),然後a0-an都出隊,因為要保持這個佇列單調遞增的性質
此時佇列為 >an+1繼續假設an+1,如果an+1 > a0 && an+1 <=a1,那麼a1-an的元素都需要-an+1;
原因同第一步,此時佇列為 >a0 an+1繼續假設an+1,如果an+1 > a1 && an+1 <=a2,那麼a2-an的元素都需要-an+1;
原因同第一步,此時佇列為 >a0 a1 an+1
...- 最後一種情況就是,如果an+1 > an,那麼就要將an+1加入這個單調遞增的佇列。
此時佇列為 > a0 a1 a2 ... an an+1
然後我們只需要迴圈上面1--4就可以了,舉個栗子給大家看看!
假設本題的序列為 8 4 9 11 5 2 6 7 9 1
初始單調遞增的序列為空a{}
1. -- 8<a0(沒有元素的時候一定入隊) -- {8}
2. -- 4<a0=8(所以a0-an出隊,並且都要減去4) -- {4}
3. -- 9>an=4(所以9入隊) -- {4 9}
4. -- 11>an=9(所以11入隊)) -- {4 9 11}
5. -- 5>a0=4 && 5<a1=9(所以9 11 出隊都減去5,然後5入隊) -- {4 5}
6. -- 2>an=5(所以4 5出隊都減去2,然後2入隊) -- {2}
7. -- 6>a0=2(所以6入隊) -- {2 6}
8. -- 7>an=6(所以7入隊) -- {2 6 7}
9. -- 9>an=7(所以9入隊)-- {2 6 7 9}
10. -- 1<a0=2(所以全部出隊都減去1,1入隊)-- {1}
******!!總結規律可以發現,我們每次比較an+1都應該從an比到a0,然後比an+1大的都出隊且減an+1,最後為
an+1找到一個合適的位置,繼續判斷an+2,這個過程由於我們需要儲存a0-an,而且比較的順序是從後往前
這不正好滿足了棧的模式麼,1記憶儲存,2從後往前,剩下的結合筆者程式碼,很容易弄懂了就。
ps:筆者也是學生,發現仔細寫個解析真的好浪費時間,真的感謝網上分享解題過程的演算法朋友們,真的辛苦了。
程式碼
c++版本
class Solution {
public:
vector<int> finalPrices(vector<int>& prices) {
stack<int> s;
int len = prices.size();
for(int i=0;i<len;i++){
if(!s.empty() && prices[i] <= prices[s.top()]){ //為空就直接push
while(!s.empty() && prices[i] <= prices[s.top()]){
int temp = s.top();
prices[temp] -= prices[i];
s.pop();
}
}
s.push(i); //儲存索引,方便再次在prices中找到這個元素
}
return prices;
}
};