回答
好吧,這裏就是你需要做的..
你需要保持一定的data structure
包含插入關於每個元素的信息,究竟是什麼minimum
並在當你插入的元素時second minimum
值..
所以,你想擁有的信息是這樣的: -
每個元素推 - 插入後>
- 最小值插入前
- 最小值
將需要此信息時,您pop
從堆棧中的元素。所以,你就知道不管你是否是popping
最小值或不是。如果是的話,那麼你可以在推送這個元素之前用minimum value
替換當前的minimum
值。如果沒有,那麼在minimum
中將沒有變化當時價值..
對於如: -
假設目前你有以下元素堆棧: -
[3, 5, 7, 9, 2, 4]
你推值8 ..然後你有兩個值來維護。 (在推入8之前的最小值,即2,以及在插入8 之後的最小值,即2): -
min_value_before_push = min(stack) push 8 min_value_after_push = min(stack)
如果你把一個值1,則
minimum_before_insertion
是2, 和minimum_after_insertion
爲1: -min_value_before_push = 2 min_value_after_push = 1
現在你的籌碼是: -
[1, 8, 3, 5, 7, 9, 2, 4]
現在,如果你pop
,你會看到,value 1
: -
min_value_before_push = 2
min_value_after_push = 1
所以,啪會改變的最小值,所以在您更改爲1 minimum_value_before_push
目前的最低值。所以,你又是最低2 ..
您當前的堆棧變爲: -
[8, 3, 5, 7, 9, 2, 4]
現在,讓我們檢查這個算法是否適用於duplicate
元素: -
假設你想再次推value 2
..
min_value_before_push = 2
min_value_after_push = 2
然後你繼續和pop
,你看到value 2
,min_value_after_push
是2,所以這意味着它突然出現將改變最小值。所以你替換min_value_before_push
這個值,這也是2 ..這是我們想要的東西..
注意: - 一個好處這種算法是,你不需要做太多比較..只是一個current_minimum_value
同時推動。而比較current_minimum_value
比較,當你pop
..
您可以嘗試進行作何感想data structure
能你有..
你是否彈出這裏的最小元素 – Jayy
@KaipaMSarma ..OP問題並沒有說我們需要彈出最小元素..它說,我們需要找到什麼是我彈出後的最小元素元素從堆棧..我認爲這是非常明確的問題.. –
我喜歡O(1)插入。聰明的stackploitation。 –
使用其他例如minStack
,當按下一個元素val
時,檢查是否val < minStack.peek()
,如果是,則將val
也推到minStack
;當從stack
彈出時,檢查彈出的值,如pop_val
,如果pop_val == minStack.peek()
是minStack.pop()
。
現在我們有一個minStack
在特定的時間點保持所有的local-min-element
(直到下一次按minStack時),我們可以通過檢查堆棧的頂端是local-min-element
,已經在上面介紹過了。
但是,只有當所有的元素都是唯一的時候,這個方法才能正常工作,否則,這樣做會更困難,提示,使用計數器:)。
聲明:禁止使用null值(就像ArrayDeque一樣),並且不經過嚴格測試。
import java.util.ArrayDeque;
public class PessimisticStack<T extends Comparable<? super T>> {
private class Entry {
private Entry(T t, T minNow) {
this.t = t;
this.minNow = minNow;
}
private final T t;
private final T minNow;
}
private final ArrayDeque<Entry> deque;
public PessimisticStack() {
deque = new ArrayDeque<Entry>();
}
public PessimisticStack(int initialCapacity) {
deque = new ArrayDeque<Entry>(initialCapacity);
}
public void push(T t) {
if (t == null) throw new NullPointerException();
Entry entry = null;
if (deque.isEmpty()) {
entry = new Entry(t, t);
}
else {
T prevMinimum = deque.peek().minNow;
T newMinimum = null;
if (t.compareTo(prevMinimum) < 0) {
newMinimum = t;
}
else {
newMinimum = prevMinimum;
}
entry = new Entry(t, newMinimum);
}
deque.push(entry);
}
public T pop() {
return deque.pop().t;
}
public T getMinimum() {
Entry entry = deque.peek();
return (entry == null ? null : entry.minNow);
}
}
使用示例
PessimisticStack<String> stack = new PessimisticStack<String>();
stack.push("Zebra");
stack.push("Elephant");
stack.push("Bryan");
stack.push("Adam");
stack.push("Calvin");
String calvin = stack.pop();
// "Adam"
System.err.println(stack.getMinimum());
stack.push("Aaron");
// "Aaron"
System.err.println(stack.getMinimum());
String aaron = stack.pop();
// "Adam"
System.err.println(stack.getMinimum());
String adam = stack.pop();
// "Bryan"
System.err.println(stack.getMinimum());
我沒有排序堆棧。我維護一個單獨的排序LinkedList。堆棧順序始終保留,不會影響LinkedList排序,它完全基於Comparable行爲,並且根本不按推送順序執行...運行示例:) –
@Joe ..是的,您是對的..剛剛看到你正在維護包含你的'Inner'類'Entry'實例的堆棧..這有點不同.. +1 .. –
@Rohit你的插入具有更好的時間複雜性,巧妙地利用堆棧行爲,所以我更新了我的代碼因此(有一個小的差異,我不跟蹤以前的最低限度;我從頭偷看得到它) –
- 1. 在圖形中維護轉換矩陣堆棧的算法
- 2. 堆棧,堆棧泛化算法
- 3. Java堆棧溢出錯誤 - 圖算法
- 4. 堆棧在java中使用堆棧
- 5. Java計算器堆棧
- 6. 排序堆棧的算法
- 7. DIY堆棧保護
- 8. 列表/樹/堆棧 - 算法
- 9. 有沒有辦法在LLVM中維護多個堆棧/指令指針?
- 10. 在Java中製作堆棧方法
- 11. Java中的堆棧溢出與Collections-Java中的堆棧實現
- 12. 受保護的堆對象堆棧vs堆棧分配
- 13. 在java中實現堆棧
- 14. 二維圖的堆棧
- 15. 關閉堆棧保護
- 16. 在Java中維護top-k
- 17. Java中的堆棧問題
- 18. Java swing中的堆棧GUI
- 19. 使用二維數組和堆棧在java中構建迷宮
- 20. Java,堆棧類
- 21. 的Java棧和堆
- 22. 一個DFS算法的Implemeting堆棧遍歷 - Java的
- 23. 堆棧vs C/Java中的堆
- 24. 計算器堆棧
- 25. 將整數的二維數組推入Java中的堆棧
- 26. 在Java中計算(不設計!)堆棧的最小值
- 27. Java堆棧方法(multipop)初學者java
- 28. 如何維護Python中的字典堆?
- 29. 無法在堆棧
- 30. 在AIX上寫保護堆棧頁面?
Errmm,[你嘗試過什麼??](http://mattgemmell.com/2008/12/08/what-have-你試過/) – Sujay
這聽起來像是一個面試問題。 (特別是,這是我申請加入Google時的面試問題。)您嘗試過什麼?這裏的背景是什麼? –
此外,只是添加@JonSkeet提到的,顯然,一點點「谷歌」 - 給你很多提示,以解決這個問題,以及:) – Sujay