Java?C++?算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧
題目要求
思路一:暴力模擬
- 由于數(shù)據(jù)范圍不算離譜,所以直接遍歷解決可行。
Java
class Solution { public int[] finalPrices(int[] prices) { int n = prices.length; int[] res = new int[n]; for (int i = 0; i < n; i++) { int discount = 0; for (int j = i + 1; j < n && discount == 0; j++) { if (prices[j] <= prices[i]) discount = prices[j]; } res[i] = prices[i] - discount; } return res; } }
- 時(shí)間復(fù)雜度:O(n^2)
- 空間復(fù)雜度:O(n)
C++
class Solution { public: vector<int> finalPrices(vector<int>& prices) { int n = prices.size(); vector<int> res(n); for (int i = 0; i < n; i++) { int discount = 0; for (int j = i + 1; j < n && discount == 0; j++) { if (prices[j] <= prices[i]) discount = prices[j]; } res[i] = prices[i] - discount; } return res; } };
- 時(shí)間復(fù)雜度:O(n^2)
- 空間復(fù)雜度:O(n)
Rust
impl Solution { pub fn final_prices(prices: Vec<i32>) -> Vec<i32> { let n = prices.len(); let mut res = vec![0;n]; (0..n).for_each(|i| { res[i] = prices[i] - ((i + 1)..n).find(|&j| prices[j] <= prices[i]).map_or(0, |j| prices[j]); }); res } }
- 遍歷存每次的count,最后再遍歷計(jì)算得出結(jié)果
impl Solution { pub fn final_prices(prices: Vec<i32>) -> Vec<i32> { let n = prices.len(); let mut discount = vec![0;n]; for j in 1..n { for i in 0..j { if discount[i] == 0 && prices[j] <= prices[i] { discount[i] = prices[j]; } } } prices.iter().zip(discount.iter()).map(|(&x, &y)| x - y).collect::<Vec<i32>>() } }
- 時(shí)間復(fù)雜度:O(n^2)
- 空間復(fù)雜度:O(n)
思路二:?jiǎn)握{(diào)棧
- 是個(gè)逆向思維,不考慮誰(shuí)是我的折扣,而去考慮我可以是誰(shuí)的折扣。已知的一個(gè)prices[j]只能折扣其左邊最近的幾個(gè)大于它的值,按這個(gè)思路分析單調(diào)和棧:
- 從前向后依次遍歷prices,遇到需要打折的商品,將其下標(biāo)放入一個(gè)容器:
- 若當(dāng)前處理值小于末尾,那么它就可以作為末尾元素的折扣【因?yàn)樗悄┪苍睾竺?strong>第一個(gè)小于它的值】,將末尾元素取出、折扣、放入已折扣數(shù)組(即結(jié)果數(shù)組),一直重復(fù)到容器末尾元素小于當(dāng)前處理值,則將當(dāng)前處理值放入容器【為避免該值不可打折造成缺漏,此時(shí)將其價(jià)格同步至已折扣數(shù)組】。
- 若當(dāng)前處理的值高于容器內(nèi)的值,那么它不能作為里面任何一者的折扣,因此直接加入容器。
- 由此可知,加入容器值會(huì)大于容器內(nèi)的其它值,該容器是單調(diào)遞增的。此外,處理的一直是容器末尾的元素,添加也是直接補(bǔ)在末尾,所以符合棧的結(jié)構(gòu)。
- 從前向后依次遍歷prices,遇到需要打折的商品,將其下標(biāo)放入一個(gè)容器:
Java
class Solution { public int[] finalPrices(int[] prices) { int n = prices.length; int[] res = new int[n]; // 已打折價(jià)格 Deque<Integer> sta = new ArrayDeque<>(); // 待打折下標(biāo) for (int i = 0; i < n; i++) { while (!sta.isEmpty() && prices[sta.peekLast()] >= prices[i]) { int idx = sta.pollLast(); res[idx] = prices[idx] - prices[i]; } sta.addLast(i); // 最高 res[i] = prices[i]; } return res; } }
- 時(shí)間復(fù)雜度:O(n)
- 空間復(fù)雜度:O(n)
C++
class Solution { public: vector<int> finalPrices(vector<int>& prices) { int n = prices.size(); vector<int> res(n); // 已打折價(jià)格 stack<int> sta; // 待打折下標(biāo) for (int i = 0; i < n; i++) { while (!sta.empty() && prices[sta.top()] >= prices[i]) { int idx = sta.top(); sta.pop(); res[idx] = prices[idx] - prices[i]; } sta.push(i); // 最高 res[i] = prices[i]; } return res; } };
- 時(shí)間復(fù)雜度:O(n)
- 空間復(fù)雜度:O(n)
Rust
impl Solution { pub fn final_prices(prices: Vec<i32>) -> Vec<i32> { let n = prices.len(); let mut res = vec![0;n]; // 已打折價(jià)格 let mut sta = vec![]; // 待打折下標(biāo) for i in 0..n { while let Some(&idx) = sta.last() { if prices[idx] < prices[i] { break; } sta.pop(); res[idx] = prices[idx] - prices[i]; } sta.push(i); // 最高 res[i] = prices[i]; } res } }
- 時(shí)間復(fù)雜度:O(n)
- 空間復(fù)雜度:O(n)
以上就是Java C++ 算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧的詳細(xì)內(nèi)容,更多關(guān)于Java C++ 商品折扣后價(jià)格的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c++實(shí)現(xiàn)一個(gè)簡(jiǎn)易的網(wǎng)絡(luò)緩沖區(qū)的實(shí)踐
這篇文章主要介紹了c++實(shí)現(xiàn)一個(gè)簡(jiǎn)易的網(wǎng)絡(luò)緩沖區(qū)的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03利用C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)小游戲
這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08C++類(lèi)與對(duì)象之運(yùn)算符重載詳解
運(yùn)算符重載的方法是定義一個(gè)重載運(yùn)算符的函數(shù),在需要執(zhí)行被重載的運(yùn)算符時(shí),系統(tǒng)就自動(dòng)調(diào)用該函數(shù),以實(shí)現(xiàn)相應(yīng)的運(yùn)算。也就是說(shuō),運(yùn)算符重載是通過(guò)定義函數(shù)實(shí)現(xiàn)的2021-10-10C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02C語(yǔ)言SetConsoleCursorInfo函數(shù)使用方法
這篇文章介紹了C語(yǔ)言SetConsoleCursorInfo函數(shù)的使用方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12c++11多線(xiàn)程編程之std::async的介紹與實(shí)例
這篇文章主要給大家介紹了關(guān)于c++11多線(xiàn)程編程之std::async的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11