import java.util.Arrays;
import java.util.NoSuchElementException;
/**
* Deque (double-ended queue) implementation which uses an array to store
* references to the objects added to the deque.
*/
class Deque<T> {
// index of the most lastly added object (-1 if no object has been added)
private int lo = -1;
// index of the most recently added object
private int hi = -1;
public void addFront(T value) {
if (lo == -1) {
data[0] = value;
lo = 0;
hi = 0;
} else {
changeArraySizeIfNeeded();
lo = dec(lo);
data[lo] = value;
}
System.
out.
printf("%-20s %s lo = %d hi = %d\n",
String.
format("addFront(%s):", value
),
Arrays.
toString(data
), lo, hi
); }
public void addBack(T value) {
if (hi == -1) {
data[0] = value;
lo = 0;
hi = 0;
} else {
changeArraySizeIfNeeded();
hi = inc(hi);
data[hi] = value;
}
System.
out.
printf("%-20s %s lo = %d hi = %d\n",
String.
format("addBack(%s):", value
),
Arrays.
toString(data
), lo, hi
); }
public T popFront() {
if (lo == -1) {
}
T value = (T) data[lo];
data[lo] = null;
if (lo == hi) {
lo = -1;
hi = -1;
} else {
lo = inc(lo);
}
changeArraySizeIfNeeded();
System.
out.
printf("%-20s %s lo = %d hi = %d\n",
String.
format("popFront() = %s:", value
),
Arrays.
toString(data
), lo, hi
); return value;
}
public T popBack() {
if (hi == -1) {
}
T value = (T) data[hi];
data[hi] = null;
if (lo == hi) {
lo = -1;
hi = -1;
} else {
hi = dec(hi);
}
changeArraySizeIfNeeded();
System.
out.
printf("%-20s %s lo = %d hi = %d\n",
String.
format("popBack() = %s:", value
),
Arrays.
toString(data
), lo, hi
); return value;
}
public T peekFront() {
if (lo == -1) {
}
return (T) data[lo];
}
public T peekBack() {
if (hi == -1) {
}
return (T) data[hi];
}
/**
* Decrements the given index in a cyclic manner (modulo data.length)
*/
private int dec(int i) {
i--;
if (i < 0) {
i += data.length;
}
return i;
}
/**
* Increments the given index in a cyclic manner (modulo data.length)
*/
private int inc(int i) {
return ++i % data.length;
}
/**
* Doubles the size of the `data` array in case it is full and
* decreases the size of `data` array twice if it is filled
* at one quarter or less
*/
private void changeArraySizeIfNeeded() {
int pureDataLength = lo < 0 ?
0 :
moduloDistance(lo, hi, data.length);
if (pureDataLength == data.length) {
data = resizeArray(data, lo, hi, 2 * data.length);
hi = pureDataLength - 1;
lo = 0;
} else if (pureDataLength != 0 && data.length / pureDataLength >= 4) {
data = resizeArray(data, lo, hi, data.length / 2);
hi = pureDataLength - 1;
lo = 0;
} else if (pureDataLength == 0) {
}
}
/**
* Computes the distance between `lo` and `hi` as if
* they were put into a cyclic array of size `n`
*/
private static int moduloDistance(int lo, int hi, int n) {
assert lo >= 0 && hi >= 0;
return lo <= hi ?
hi - lo + 1 :
n - lo + hi + 1;
}
/**
* Copies the given array into a new one of the {@code newSize} size
* @param src the source array
* @param lo points to the first element in the sequence to be copied
* @param hi points to the last element in the sequence to be copied.
* It is not necessary for `lo` to be less, than `hi`:
* this method copies the data from the `src` as if it would be cyclic
* @param newSize size of the resulting array
*/
private static Object[] resizeArray
(Object[] src,
int lo,
int hi,
int newSize
) { assert newSize >= 0;
assert moduloDistance(lo, hi, src.length) <= newSize;
if (lo <= hi) {
System.
arraycopy(src, lo, resizedArray,
0, hi
- lo
+ 1); } else {
System.
arraycopy(src, lo, resizedArray,
0, src.
length - lo
); System.
arraycopy(src,
0, resizedArray, src.
length - lo, hi
+ 1); }
return resizedArray;
}
public static void main
(String[] args
) { Deque<Integer> deque = new Deque<>();
for (int i = 3; i >= 0; i--) {
deque.addFront(i);
}
for (int i = 4; i <= 7; i++) {
deque.addBack(i);
}
for (int i = 0; i < 4; i++) {
deque.popFront();
deque.popBack();
}
deque.addBack(1);
deque.addFront(0);
}
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKIAovKioKICogRGVxdWUgKGRvdWJsZS1lbmRlZCBxdWV1ZSkgaW1wbGVtZW50YXRpb24gd2hpY2ggdXNlcyBhbiBhcnJheSB0byBzdG9yZQogKiByZWZlcmVuY2VzIHRvIHRoZSBvYmplY3RzIGFkZGVkIHRvIHRoZSBkZXF1ZS4KICovCmNsYXNzIERlcXVlPFQ+IHsKICAgIHByaXZhdGUgT2JqZWN0W10gZGF0YSA9IG5ldyBPYmplY3RbMV07CiAgICAvLyBpbmRleCBvZiB0aGUgbW9zdCBsYXN0bHkgYWRkZWQgb2JqZWN0ICgtMSBpZiBubyBvYmplY3QgaGFzIGJlZW4gYWRkZWQpCiAgICBwcml2YXRlIGludCBsbyA9IC0xOwogICAgLy8gaW5kZXggb2YgdGhlIG1vc3QgcmVjZW50bHkgYWRkZWQgb2JqZWN0CiAgICBwcml2YXRlIGludCBoaSA9IC0xOwogCiAgICBwdWJsaWMgdm9pZCBhZGRGcm9udChUIHZhbHVlKSB7CiAgICAgICAgaWYgKGxvID09IC0xKSB7CiAgICAgICAgICAgIGRhdGFbMF0gPSB2YWx1ZTsKICAgICAgICAgICAgbG8gPSAwOwogICAgICAgICAgICBoaSA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2hhbmdlQXJyYXlTaXplSWZOZWVkZWQoKTsKICAgICAgICAgICAgbG8gPSBkZWMobG8pOwogICAgICAgICAgICBkYXRhW2xvXSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiJS0yMHMgJXMgbG8gPSAlZCBoaSA9ICVkXG4iLCBTdHJpbmcuZm9ybWF0KCJhZGRGcm9udCglcyk6IiwgdmFsdWUpLCBBcnJheXMudG9TdHJpbmcoZGF0YSksIGxvLCBoaSk7CiAgICB9CiAKICAgIHB1YmxpYyB2b2lkIGFkZEJhY2soVCB2YWx1ZSkgewogICAgICAgIGlmIChoaSA9PSAtMSkgewogICAgICAgICAgICBkYXRhWzBdID0gdmFsdWU7CiAgICAgICAgICAgIGxvID0gMDsKICAgICAgICAgICAgaGkgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoYW5nZUFycmF5U2l6ZUlmTmVlZGVkKCk7CiAgICAgICAgICAgIGhpID0gaW5jKGhpKTsKICAgICAgICAgICAgZGF0YVtoaV0gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIiUtMjBzICVzIGxvID0gJWQgaGkgPSAlZFxuIiwgU3RyaW5nLmZvcm1hdCgiYWRkQmFjayglcyk6IiwgdmFsdWUpLCBBcnJheXMudG9TdHJpbmcoZGF0YSksIGxvLCBoaSk7CiAgICB9CiAKICAgIHB1YmxpYyBUIHBvcEZyb250KCkgewogICAgICAgIGlmIChsbyA9PSAtMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigiVGhlIGRlcXVlIGlzIGVtcHR5Iik7CiAgICAgICAgfQogCiAgICAgICAgVCB2YWx1ZSA9IChUKSBkYXRhW2xvXTsKICAgICAgICBkYXRhW2xvXSA9IG51bGw7CiAgICAgICAgaWYgKGxvID09IGhpKSB7CiAgICAgICAgICAgIGxvID0gLTE7CiAgICAgICAgICAgIGhpID0gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbG8gPSBpbmMobG8pOwogICAgICAgIH0KICAgICAgICBjaGFuZ2VBcnJheVNpemVJZk5lZWRlZCgpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRmKCIlLTIwcyAlcyBsbyA9ICVkIGhpID0gJWRcbiIsIFN0cmluZy5mb3JtYXQoInBvcEZyb250KCkgPSAlczoiLCB2YWx1ZSksIEFycmF5cy50b1N0cmluZyhkYXRhKSwgbG8sIGhpKTsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICB9CiAKICAgIHB1YmxpYyBUIHBvcEJhY2soKSB7CiAgICAgICAgaWYgKGhpID09IC0xKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCJUaGUgZGVxdWUgaXMgZW1wdHkiKTsKICAgICAgICB9CiAKICAgICAgICBUIHZhbHVlID0gKFQpIGRhdGFbaGldOwogICAgICAgIGRhdGFbaGldID0gbnVsbDsKICAgICAgICBpZiAobG8gPT0gaGkpIHsKICAgICAgICAgICAgbG8gPSAtMTsKICAgICAgICAgICAgaGkgPSAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBoaSA9IGRlYyhoaSk7CiAgICAgICAgfQogICAgICAgIGNoYW5nZUFycmF5U2l6ZUlmTmVlZGVkKCk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIiUtMjBzICVzIGxvID0gJWQgaGkgPSAlZFxuIiwgU3RyaW5nLmZvcm1hdCgicG9wQmFjaygpID0gJXM6IiwgdmFsdWUpLCBBcnJheXMudG9TdHJpbmcoZGF0YSksIGxvLCBoaSk7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQogCiAgICBwdWJsaWMgVCBwZWVrRnJvbnQoKSB7CiAgICAgICAgaWYgKGxvID09IC0xKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCJUaGUgZGVxdWUgaXMgZW1wdHkiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChUKSBkYXRhW2xvXTsKICAgIH0KIAogICAgcHVibGljIFQgcGVla0JhY2soKSB7CiAgICAgICAgaWYgKGhpID09IC0xKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCJUaGUgZGVxdWUgaXMgZW1wdHkiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChUKSBkYXRhW2hpXTsKICAgIH0KIAogICAgLyoqCiAgICAgKiBEZWNyZW1lbnRzIHRoZSBnaXZlbiBpbmRleCBpbiBhIGN5Y2xpYyBtYW5uZXIgKG1vZHVsbyBkYXRhLmxlbmd0aCkKICAgICAqLwogICAgcHJpdmF0ZSBpbnQgZGVjKGludCBpKSB7CiAgICAgICAgaS0tOwogICAgICAgIGlmIChpIDwgMCkgewogICAgICAgICAgICBpICs9IGRhdGEubGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaTsKICAgIH0KIAogICAgLyoqCiAgICAgKiBJbmNyZW1lbnRzIHRoZSBnaXZlbiBpbmRleCBpbiBhIGN5Y2xpYyBtYW5uZXIgKG1vZHVsbyBkYXRhLmxlbmd0aCkKICAgICAqLwogICAgcHJpdmF0ZSBpbnQgaW5jKGludCBpKSB7CiAgICAgICAgcmV0dXJuICsraSAlIGRhdGEubGVuZ3RoOwogICAgfQogCiAgICAvKioKICAgICAqIERvdWJsZXMgdGhlIHNpemUgb2YgdGhlIGBkYXRhYCBhcnJheSBpbiBjYXNlIGl0IGlzIGZ1bGwgYW5kCiAgICAgKiBkZWNyZWFzZXMgdGhlIHNpemUgb2YgYGRhdGFgIGFycmF5IHR3aWNlIGlmIGl0IGlzIGZpbGxlZAogICAgICogYXQgb25lIHF1YXJ0ZXIgb3IgbGVzcwogICAgICovCiAgICBwcml2YXRlIHZvaWQgY2hhbmdlQXJyYXlTaXplSWZOZWVkZWQoKSB7CiAgICAgICAgaW50IHB1cmVEYXRhTGVuZ3RoID0gbG8gPCAwID8KICAgICAgICAgICAgICAgIDAgOgogICAgICAgICAgICAgICAgbW9kdWxvRGlzdGFuY2UobG8sIGhpLCBkYXRhLmxlbmd0aCk7CiAKICAgICAgICBpZiAocHVyZURhdGFMZW5ndGggPT0gZGF0YS5sZW5ndGgpIHsKICAgICAgICAgICAgZGF0YSA9IHJlc2l6ZUFycmF5KGRhdGEsIGxvLCBoaSwgMiAqIGRhdGEubGVuZ3RoKTsKICAgICAgICAgICAgaGkgPSBwdXJlRGF0YUxlbmd0aCAtIDE7CiAgICAgICAgICAgIGxvID0gMDsKICAgICAgICB9IGVsc2UgaWYgKHB1cmVEYXRhTGVuZ3RoICE9IDAgJiYgZGF0YS5sZW5ndGggLyBwdXJlRGF0YUxlbmd0aCA+PSA0KSB7CiAgICAgICAgICAgIGRhdGEgPSByZXNpemVBcnJheShkYXRhLCBsbywgaGksIGRhdGEubGVuZ3RoIC8gMik7CiAgICAgICAgICAgIGhpID0gcHVyZURhdGFMZW5ndGggLSAxOwogICAgICAgICAgICBsbyA9IDA7CiAgICAgICAgfSBlbHNlIGlmIChwdXJlRGF0YUxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIGRhdGEgPSBuZXcgT2JqZWN0WzFdOwogICAgICAgIH0KICAgIH0KIAogICAgLyoqCiAgICAgKiBDb21wdXRlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiBgbG9gIGFuZCBgaGlgIGFzIGlmCiAgICAgKiB0aGV5IHdlcmUgcHV0IGludG8gYSBjeWNsaWMgYXJyYXkgb2Ygc2l6ZSBgbmAKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgaW50IG1vZHVsb0Rpc3RhbmNlKGludCBsbywgaW50IGhpLCBpbnQgbikgewogICAgICAgIGFzc2VydCBsbyA+PSAwICYmIGhpID49IDA7CiAKICAgICAgICByZXR1cm4gbG8gPD0gaGkgPwogICAgICAgICAgICBoaSAtIGxvICsgMSA6CiAgICAgICAgICAgIG4gLSBsbyArIGhpICsgMTsKICAgIH0KIAogICAgLyoqCiAgICAgKiBDb3BpZXMgdGhlIGdpdmVuIGFycmF5IGludG8gYSBuZXcgb25lIG9mIHRoZSB7QGNvZGUgbmV3U2l6ZX0gc2l6ZQogICAgICogQHBhcmFtIHNyYyB0aGUgc291cmNlIGFycmF5CiAgICAgKiBAcGFyYW0gbG8gcG9pbnRzIHRvIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSBzZXF1ZW5jZSB0byBiZSBjb3BpZWQKICAgICAqIEBwYXJhbSBoaSBwb2ludHMgdG8gdGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgc2VxdWVuY2UgdG8gYmUgY29waWVkLgogICAgICogICAgICAgICAgIEl0IGlzIG5vdCBuZWNlc3NhcnkgZm9yIGBsb2AgdG8gYmUgbGVzcywgdGhhbiBgaGlgOgogICAgICogICAgICAgICAgIHRoaXMgbWV0aG9kIGNvcGllcyB0aGUgZGF0YSBmcm9tIHRoZSBgc3JjYCBhcyBpZiBpdCB3b3VsZCBiZSBjeWNsaWMKICAgICAqIEBwYXJhbSBuZXdTaXplIHNpemUgb2YgdGhlIHJlc3VsdGluZyBhcnJheQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBPYmplY3RbXSByZXNpemVBcnJheShPYmplY3RbXSBzcmMsIGludCBsbywgaW50IGhpLCBpbnQgbmV3U2l6ZSkgewogICAgICAgIGFzc2VydCBuZXdTaXplID49IDA7CiAgICAgICAgYXNzZXJ0IG1vZHVsb0Rpc3RhbmNlKGxvLCBoaSwgc3JjLmxlbmd0aCkgPD0gbmV3U2l6ZTsKIAogICAgICAgIE9iamVjdFtdIHJlc2l6ZWRBcnJheSA9IG5ldyBPYmplY3RbbmV3U2l6ZV07CiAgICAgICAgaWYgKGxvIDw9IGhpKSB7CiAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCBsbywgcmVzaXplZEFycmF5LCAwLCBoaSAtIGxvICsgMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShzcmMsIGxvLCByZXNpemVkQXJyYXksIDAsIHNyYy5sZW5ndGggLSBsbyk7CiAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoc3JjLCAwLCByZXNpemVkQXJyYXksIHNyYy5sZW5ndGggLSBsbywgaGkgKyAxKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc2l6ZWRBcnJheTsKICAgIH0KIAogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIERlcXVlPEludGVnZXI+IGRlcXVlID0gbmV3IERlcXVlPD4oKTsKICAgICAgICBmb3IgKGludCBpID0gMzsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgZGVxdWUuYWRkRnJvbnQoaSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSA0OyBpIDw9IDc7IGkrKykgewogICAgICAgICAgICBkZXF1ZS5hZGRCYWNrKGkpOwogICAgICAgIH0KICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKykgewogICAgICAgICAgICBkZXF1ZS5wb3BGcm9udCgpOwogICAgICAgICAgICBkZXF1ZS5wb3BCYWNrKCk7CiAgICAgICAgfQogICAgICAgIGRlcXVlLmFkZEJhY2soMSk7CiAgICAgICAgZGVxdWUuYWRkRnJvbnQoMCk7CiAgICB9Cn0=
addFront(3): [3] lo = 0 hi = 0
addFront(2): [3, 2] lo = 1 hi = 0
addFront(1): [2, 3, null, 1] lo = 3 hi = 1
addFront(0): [2, 3, 0, 1] lo = 2 hi = 1
addBack(4): [0, 1, 2, 3, 4, null, null, null] lo = 0 hi = 4
addBack(5): [0, 1, 2, 3, 4, 5, null, null] lo = 0 hi = 5
addBack(6): [0, 1, 2, 3, 4, 5, 6, null] lo = 0 hi = 6
addBack(7): [0, 1, 2, 3, 4, 5, 6, 7] lo = 0 hi = 7
popFront() = 0: [null, 1, 2, 3, 4, 5, 6, 7] lo = 1 hi = 7
popBack() = 7: [null, 1, 2, 3, 4, 5, 6, null] lo = 1 hi = 6
popFront() = 1: [null, null, 2, 3, 4, 5, 6, null] lo = 2 hi = 6
popBack() = 6: [null, null, 2, 3, 4, 5, null, null] lo = 2 hi = 5
popFront() = 2: [null, null, null, 3, 4, 5, null, null] lo = 3 hi = 5
popBack() = 5: [3, 4, null, null] lo = 0 hi = 1
popFront() = 3: [4, null] lo = 0 hi = 0
popBack() = 4: [null] lo = -1 hi = -1
addBack(1): [1] lo = 0 hi = 0
addFront(0): [1, 0] lo = 1 hi = 0