スタックからポップするたびに、スタック内の最小要素がわかるように、スタックをどのように維持しますか? アルゴリズムは一定の複雑さを持つ必要があります
前もって感謝します
スタックからポップするたびに、スタック内の最小要素がわかるように、スタックをどのように維持しますか? アルゴリズムは一定の複雑さを持つ必要があります
前もって感謝します
わかりました、これがあなたがする必要があることです..
data structure
挿入する各要素の含まれている情報、その要素を挿入したときの値は何かを維持する必要がありminimum
ます。second minimum
したがって、次のような情報が必要です。
押された要素ごとに ->
この情報は、その要素をスタックから取得するときに必要になります。したがって、最小値pop
であるかどうかがわかります。そうであれば、この要素をプッシュする前に現在の値を に置き換えることができます。そうでない場合は、その時点での価値の変化はありません..popping
minimum
minimum value
minimum
例: -
現在、スタックに次の要素があるとします: -
[3, 5, 7, 9, 2, 4]
そして、値 8をプッシュします..次に、維持する値が 2 つあります..(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
したがって、ポップすると最小値が変更されます。したがって、現在の最小値をminimum_value_before_push
1.. で変更します。したがって、最小値は 2..
現在のスタックは : -
[8, 3, 5, 7, 9, 2, 4]
それでは、このアルゴリズムが要素に対して機能するかどうかを確認しましょうduplicate
: -
もう一度押したいとvalue 2
します..
min_value_before_push = 2
min_value_after_push = 2
次に進むと、pop
for が 2 であることがわかります。これは、ポップすると最小値が変更されることを意味します。したがって、この値を に置き換えます。これも 2 です。value 2
min_value_after_push
min_value_before_push
注: - このアルゴリズムの利点の 1 つは、多くの比較を行う必要がないことcurrent_minimum_value
です。current_minimum_value
pop
あなたは何ができるかを考え続けることdata structure
ができます..
免責事項: 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());
minStack
たとえば、要素をプッシュするときに別のスタックを使用し、プッシュする場合はプッシュval
するかどうかを確認します。から pop するときは、値 pop を確認します。val < minStack.peek()
val
minStack
stack
pop_val
minStack.pop()
pop_val == minStack.peek()
特定の時点 (minStack への次のプッシュが行われるまで) をすべて保持する ができたので、スタックのトップが であるかどうかを確認するだけで、いつ minStack からポップするかを簡単に判断できminStack
ます。すでに上で紹介しました。local-min-element
local-min-element
ただし、このメソッドは、すべての要素が互いに一意である場合にのみ適切に機能します。それ以外の場合は、カウンターを使用すること、ヒント、使用することが少し難しくなります:)。