Design Front Middle Back Queue 设计前中后队列
Description
Design a queue that supports push
and pop
operations in the front, middle, and back.
- Pushing
6
into the middle of[1, 2, 3, 4, 5]
results in[1, 2, 6, 3, 4, 5]
. - Popping the middle from
[1, 2, 3, 4, 5, 6]
returns3
and results in[1, 2, 4, 5, 6]
.
思路
通过2个双端队列拼接,实现一个队列的前中后插入删除
class FrontMiddleBackQueue {
public class Node {
int val;
Node next;
Node pre;
public Node(int val) {
this.val = val;
this.next = null;
this.pre = null;
}
public void insert_pre(Node p){
p.pre = pre;
p.next = this;
if (this.pre!=null){
this.pre.next =p;
}
this.pre =p;
return;
}
public void insert_next(Node p){
p.next = this.next;
p.pre = this;
if (this.next!=null){
this.next.pre = p;
}
this.next =p;
return;
}
public void del_pre(){
if(this.pre ==null){
return;
}
Node p = this.pre;
this.pre = p.pre;
if (p.pre!=null){
p.pre.next = this;
}
return;
}
public void del_next(){
if(this.next ==null){
return;
}
Node p = this.next;
this.next = p.next;
if (p.next!=null){
p.next.pre = this;
}
return;
}
}
public class Queue {
public Node head;//头节点,head中不存数据
public Node tail;//尾节点后一位,tail不存数据
public int cnt;//队列中元素个数
Queue(){
cnt = 0;
tail = new Node(0);
head = new Node(0);
head.next = tail;
head.pre =null;
tail.next = null;
tail.pre = head;
}
public int size(){
return cnt;
}
public boolean isEmpty(){
return head.next == tail;
}
//尾部入队 ,tail前插
void push_back(int val){
tail.insert_pre(new Node(val));
cnt+=1;
}
//头部入队,head后插
void push_front(int val){
head.insert_next(new Node(val));
cnt+=1;
}
//尾部出队,tail前删
int pop_back(){
if (isEmpty()){
return -1;
}
int ret = tail.pre.val;
tail.del_pre();
cnt-=1;
return ret;
}
//头部出队,head后删
int pop_front(){
if (isEmpty()){
return -1;
}
int ret = head.next.val;
head.del_next();
cnt-=1;
return ret;
}
//获取队首值
int front(){
return head.next.val;
}
int back(){
return tail.pre.val;
}
}
public Queue q1;
public Queue q2;
public FrontMiddleBackQueue() {
q1 = new Queue();
q2 = new Queue();
}
boolean isEmpty(){
return q1.size() ==0;
}
//调整队列平衡 一般q1比q2多一个
void update(){
if (q1.size()<q2.size()){
q1.push_back(q2.front());
q2.pop_front();
}
if(q1.size()==q2.size()+2){
q2.push_front(q1.back());
q1.pop_back();
}
}
//队列前插
void pushFront(int val){
q1.push_front(val);
update();
}
//队列中插,在调整后插入q1尾
void pushMiddle(int val){
if (q1.size()>q2.size()){
q2.push_front(q1.back());
q1.pop_back();
}
q1.push_back(val);
}
//队列尾插
void pushBack(int val){
q2.push_back(val);
update();
}
//队首出队
int popFront(){
if (isEmpty()){
return -1;
}
int ret = q1.pop_front();
update();
return ret;
}
//队中出队,q1尾出,update
int popMiddle(){
if (isEmpty()){
return -1;
}
int ret = q1.pop_back();
update();;
return ret;
}
//队尾出队,一般q2尾出,也有可能q1 尾出
int popBack(){
if (isEmpty()){
return -1;
}
int ret;
if (!q2.isEmpty()){
ret =q2.pop_back();
}
else {
ret = q1.pop_back();
}
update();
return ret;
}
}
/**
* Your FrontMiddleBackQueue object will be instantiated and called as such:
* FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
* obj.pushFront(val);
* obj.pushMiddle(val);
* obj.pushBack(val);
* int param_4 = obj.popFront();
* int param_5 = obj.popMiddle();
* int param_6 = obj.popBack();
*/