いんちきは、スタックとキューの両方の特性を組み合わせたデータ構造です。3つの操作が可能であることは右のように左から書かれた要素のリストとして見ることができます。
push(x)
:新しいアイテムを追加しx
、リストの左端にpop()
:リストの左端の項目を削除して返しますpull()
:リストの右端の項目を削除します。
3つのスタックおよび使用いんちき実装 O(1)
任意のプッシュ、ポップ、またはプル操作のための償却時間があるので、こと、追加のメモリを O(1)
。
あなたのソリューション。
1.スタックS1プッシュ/ポップのために、スタックS3プルため、スタックS2はS1のコピーです。
2.インスタンス変数は、残りの要素の数を追跡し続けるためにSZ。
3.プッシュ:S1およびS2に同じ要素をプッシュ。ポップ:最初のチェックSZを、SZ == 0、明確なs1が、そうでないs1.pop行う場合()。プル:最初のチェックSZ、SZ == 0、明確なS1であれば、S3の要素がないそうでない場合は、S3にS2内のすべてのコピーの要素をポップし、s3.popを行います()。
S1 / S3のポップ/プルが互いに同期していないので、szはここで必要とされています。すべての要素は、いずれかpoped引きされている場合でも、S1またはS3はまだ、すでに/ポップ引っ張ってきた要素を有することができます。したがって、各時間szが0になり、私たちは、S1とS3の両方をクリアする必要があります。
ランタイム/スペースの複雑さ:
スペースがプッシュされる各要素についてはO(N)で、私たちは、S2で余分なコピーを格納します。
時間:プッシュ:O(1)。ポップ:szが0でない限り、S1を空にされることはありません。szが0のとき、我々はO(N)時間をとる、S1とS3の両方をクリアする必要があります。ポップは、O(1)時間を償却しているので、これは、N POPまたはプル操作の後起こります。プル:それはS2からS3へのコピー要素をプッシュする別のO(N)時間を要することを除いて、ポップと似ています。また、O(1)時間を償却しています。
パブリック クラスクワック{ プライベート クラス EmptyQuackExceptionは、拡張例外{ 文字列のエラー =「クワック例外を空にします!」; } プライベート int型SZ。 プライベートスタック<整数> S1、S2、S3; パブリッククワック(){ S1 = 新しいスタック<> (); S2 = 新しいスタック<> (); S3 = 新しいスタック<> (); } / * 左の端に新しい要素を追加するとき、S1とS2の両方にそれを行います * / パブリック 無効プッシュ(int型V){ s1.push(V); s2.push(V); SZ ++ ; } / * 左ない要素、スロー例外が存在しない場合、左端からpoping。 それ以外の場合は、S2とS1にポップ。 * / 公共 int型のポップ()がスローEmptyQuackException { 場合(SZ == 0 ){ s1.clear()。
s3.clear(); スロー 新しいEmptyQuackExceptionを(); } )(s2.pop。 SZ - ; リターンs1.pop(); } / * 残された要素、スロー例外が存在しない場合は、右端から飛び出ます。 S3の要素がある場合はそれ以外の場合は、確認してください。ある場合は、単純にポップ。 何も存在しない場合には、S3からポップ、S3にS2内のすべての要素を逆転。 * / パブリック int型プル()スローEmptyQuackException { 場合(SZ == 0 ){ s1.clear()。
s3.clear(); スロー 新しいEmptyQuackExceptionを(); } そう であれば(s3.size()== 0 ){ 一方(s2.size()> 0){ s3.push(s2.pop())。 } } SZ - 。 リターンs3.pop(); } }
社説:
押す:左のスタックにプッシュします。
ポップ:左と右の両方のスタックは空、スロー例外であれば、左のスタックの要素がない場合はそれ以外の場合は、その後、その後、右のスタックにauxillaryバック内のすべての要素をポップ、左スタックに残りの半分をポップ、auxillaryスタックに右のスタックからの要素の半分をポップ。
プル:ポップと似ています。
ここで重要な点は、左が空の場合、我々は左とスタックは逆の順序になっているので、右のスタックの下半分を取得する必要があるということです。我々は、第1のバッファスタックに右の上半分をpoping右の下半分を露出するようにします。そして、右から左に下半分をpopingによって、我々はまた、これらの下半分の要素の順序を逆転させました。最後に、我々は右のスタックにバッファスタックから上半分のバックを入れて、そのままトップの半分の秩序を維持し、自然にバッファに要素をpoping、バック、そのバッファからそれらをpopingによって維持プロパティする必要があります!
ランタイム/スペースの複雑さ:
スペース:O(1)、余分なコピー
ランタイム:再均衡操作はに比例する時間を要します O(N)
。我々は両方のスタック上のN / 2の要素を保証しているので、それぞれの再バランスの間にN / 2プルまたはポップ操作よりも少ないがあってはなりません。したがって、我々はのための時間を償却することを言うことができる pop
と pull
、それぞれがあります O(1)
。それぞれの走行時間 push
操作があります O(1)
。
public class BalancedQuack { private class EmptyQuackException extends Exception{ String error = "Empty Quack Exception!"; } private Stack<Integer> left, right, auxillary; public BalancedQuack() { left = new Stack<>(); right = new Stack<>(); auxillary = new Stack<>(); } public void push(int v) { left.push(v); } public int pop() throws EmptyQuackException { if(left.size() == 0 && right.size() == 0) { throw new EmptyQuackException(); } else if(left.size() == 0) { for(int i = 0; i < right.size() / 2; i++) { auxillary.push(right.pop()); } while(right.size() > 0) { left.push(right.pop()); } while(auxillary.size() > 0) { right.push(auxillary.pop()); } } return left.pop(); } public int pull() throws EmptyQuackException { if(left.size() == 0 && right.size() == 0) { throw new EmptyQuackException(); } else if(right.size() == 0) { for(int i = 0; i < left.size() / 2; i++) { auxillary.push(left.pop()); } while(left.size() > 0) { right.push(left.pop()); } while(auxillary.size() > 0) { left.push(auxillary.pop()); } } return right.pop(); } }