题目
请你设计一个队列,支持在前,中,后三个位置的 push 和 pop 操作。
请你完成 FrontMiddleBack 类:
- FrontMiddleBack() 初始化队列。
- void pushFront(int val) 将 val 添加到队列的 最前面 。
- void pushMiddle(int val) 将 val 添加到队列的 正中间 。
- void pushBack(int val) 将 val 添加到队里的 最后面 。
- int popFront() 将 最前面 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1 。
- int popMiddle() 将 正中间 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1 。
- int popBack() 将 最后面 的元素从队列中删除并返回值,如果删除之前队列为空,那么返回 -1 。
请注意当有 两个 中间位置的时候,选择靠前面的位置进行操作。比方说:
- 将 6 添加到 [1, 2, 3, 4, 5] 的中间位置,结果数组为 [1, 2, 6, 3, 4, 5] 。
- 从 [1, 2, 3, 4, 5, 6] 的中间位置弹出元素,返回 3 ,数组变为 [1, 2, 4, 5, 6] 。
示例 1:
输入:
["FrontMiddleBackQueue", "pushFront", "pushBack", "pushMiddle", "pushMiddle", "popFront", "popMiddle", "popMiddle", "popBack", "popFront"]
[[], [1], [2], [3], [4], [], [], [], [], []]
输出:
[null, null, null, null, null, 1, 3, 4, 2, -1]
解释:
FrontMiddleBackQueue q = new FrontMiddleBackQueue();
q.pushFront(1); // [1]
q.pushBack(2); // [1, 2]
q.pushMiddle(3); // [1, 3, 2]
q.pushMiddle(4); // [1, 4, 3, 2]
q.popFront(); // 返回 1 -> [4, 3, 2]
q.popMiddle(); // 返回 3 -> [4, 2]
q.popMiddle(); // 返回 4 -> [2]
q.popBack(); // 返回 2 -> []
q.popFront(); // 返回 -1 -> [] (队列为空)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-front-middle-back-queue
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
使用两个数组
class FrontMiddleBackQueue {
int size1 = 0;
int size2 = 0;
ArrayList<Integer> arr1;
ArrayList<Integer> arr2;
public FrontMiddleBackQueue() {
arr1 = new ArrayList<>();
arr2 = new ArrayList<>();
}
public void pushFront(int val) {
arr1.add(0,val);
size1++;
}
public void pushMiddle(int val) {
while(size1 > size2){
size1--;
size2++;
arr2.add(0,arr1.remove(size1));
}
while(size2 > size1 + 1){
size2--;
size1++;
arr1.add(arr2.remove(0));
}
arr1.add(val);
size1++;
}
public void pushBack(int val) {
arr2.add(val);
size2++;
}
public int popFront() {
if(size1 == 0 && size2 == 0){
return -1;
}
if(size1 > 0){
size1--;
return arr1.remove(0);
}
size2--;
return arr2.remove(0);
}
public int popMiddle() {
if(size1 == 0 && size2 == 0) return -1;
while(size1 > size2){
size1--;
size2++;
arr2.add(0,arr1.remove(size1));
}
while(size2 > size1 + 1){
size2--;
size1++;
arr1.add(arr2.remove(0));
}
if(size1 == size2){
size1--;
return arr1.remove(size1);
}
size2--;
return arr2.remove(0);
}
public int popBack() {
if(size1 == 0 && size2 == 0) return -1;
if(size2 > 0){
size2--;
return arr2.remove(size2);
}
size1--;
return arr1.remove(size1);
}
}
使用链表
class FrontMiddleBackQueue {
private NodeList head;
private NodeList tail;
private NodeList p;
private int count;
public FrontMiddleBackQueue() {
head = null;
count = 0;
}
public void pushFront(int val) {
p = new NodeList(val,head);
head = p;
count++;
if(count == 1)tail = head;
}
public void pushMiddle(int val) {
int index = count / 2;
NodeList pre = new NodeList(0,head);
p = pre;
while(index-- > 0){
p = p.next;
}
p.next = new NodeList(val,p.next);
count++;
head = pre.next;
if(count == 1){
tail = head;
}
}
public void pushBack(int val) {
if(count == 0){
tail = new NodeList(val,null);
count++;
head = tail;
}
else{
tail.next = new NodeList(val,null);
count++;
tail = tail.next;
}
}
public int popFront() {
if(count == 0) return -1;
int v = head.value;
head = head.next;
count--;
if(count == 0) tail = head;
return v;
}
public int popMiddle() {
if(count == 0) return -1;
int index = (count - 1) / 2;
p = new NodeList(0,head);
while(index-- > 0){
p = p.next;
}
int v = p.next.value;
if(p.next.next == null){
head = null;
tail = null;
count--;
return v;
}
p.next = p.next.next;
count--;
if(count == 1) head = tail;
return v;
}
public int popBack() {
if(count == 0) return -1;
int v = tail.value;
NodeList pre = new NodeList(0,head);
p = pre;
for(int i = 1;i < count;i++){
p = p.next;
}
p.next = p.next.next;
count--;
if(count == 0) {
tail = null;
head = null;
}
else{
tail = p;
}
return v;
}
}
class NodeList{
int value;
NodeList next;
NodeList(int value, NodeList next){
this.value = value;
this.next = next;
}
}