时间:2022-06-06 09:32:17 | 栏目:JAVA代码 | 点击:次
循环队列一般通过数组实现。我们需要解决几个问题。
a、下标最后再往后(offset 小于 array.length): index = (index + offset) % array.length。通俗一点,就是如果我们的数组大小为8,下标走到了7,再往后如何回到0,我们可以(index+1)%8来实现。

b、下标最前再往前的时候,我们特殊判断一下,将其置为数组大小减一即可。
我们可以给数组预留一个位置,如果rear+1=front,则表示队列已满;如果rear=front,表示队列为空。这个情况下,我们需要考虑队列大小的问题,在定义数组大小时,需要比原有的大一。

【代码如下】
class MyCircularQueue {
public int front;
public int rear;
public int[] array;
//构造方法
public MyCircularQueue(int k) {
//因为预留位置的缘故,数组的大小要定义为k+1
this.array=new int[k+1];
}
//入队
public boolean enQueue(int value) {
if(isFull()){
return false;
}
this.array[this.rear]=value;
this.rear=(this.rear+1)%this.array.length;
return true;
}
//出队
public boolean deQueue() {
if(isEmpty()){
return false;
}
this.front=(this.front+1)%this.array.length;
return true;
}
//获取队头
public int Front() {
if(isEmpty()){
return -1;
}
return this.array[front];
}
//获取队尾
public int Rear() {
if(isEmpty()){
return -1;
}
int index=-1;
if(this.rear==0){
index=this.array.length-1;
}else{
index=this.rear-1;
}
return this.array[index];
}
//判断是否为空
public boolean isEmpty() {
if(this.front==this.rear){
return true;
}
return false;
}
//判断队列是否满
public boolean isFull() {
if((this.rear+1)%this.array.length==this.front){
return true;
}
return false;
}
}
因为栈的先进后出、队列的先进先出原则。我们需要两个队列来实现栈。当两个队列都为空时,栈为空。
【代码如下】
class MyStack {
private Queue<Integer> queue1;
private Queue<Integer> queue2;
//构造方法
public MyStack() {
queue1=new LinkedList<>();
queue2=new LinkedList<>();
}
//入栈
public void push(int x) {
if(!queue2.isEmpty()){
queue2.offer(x);
}else{
queue1.offer(x);
}
}
//出栈
public int pop() {
if(empty()){
return -1;
}
if(queue1.isEmpty()){
int size=queue2.size();
for(int i=0;i<size-1;++i){
int x=queue2.poll();
queue1.offer(x);
}
return queue2.poll();
}else{
int size=queue1.size();
for(int i=0;i<size-1;++i){
int x=queue1.poll();
queue2.offer(x);
}
return queue1.poll();
}
}
//获取栈顶元素
public int top() {
if(empty()){
return -1;
}
if(queue1.isEmpty()){
int x=-1;
int size=queue2.size();
for(int i=0;i<size;++i){
x=queue2.poll();
queue1.offer(x);
}
return x;
}else{
int size=queue1.size();
int x=-1;
for(int i=0;i<size;++i){
x=queue1.poll();
queue2.offer(x);
}
return x;
}
}
//判断栈是否为空
public boolean empty() {
if(queue1.isEmpty()&&queue2.isEmpty()){
return true;
}
return false;
}
}
还是和上面一样,需要用到两个栈(stack1、stack2)。和实现栈列不同的是,入队只能对同一个栈进行操作。如果两个栈都为空,则队列为空。
【代码如下】
class MyQueue {
private Stack<Integer> stack1;
private Stack<Integer> stack2;
//构造方法
public MyQueue() {
stack1=new Stack<>();
stack2=new Stack<>();
}
//入队操作
public void push(int x) {
stack1.push(x);
}
//出队操作
public int pop() {
if(stack2.empty()){
int size=stack1.size();
for(int i=0;i<size;++i){
int x=stack1.pop();
stack2.push(x);
}
}
return stack2.pop();
}
//获取队列开头的元素
public int peek() {
if(stack2.empty()){
int size=stack1.size();
for(int i=0;i<size;++i){
int x=stack1.pop();
stack2.push(x);
}
}
return stack2.peek();
}
//判断队列是否为空
public boolean empty() {
if(stack1.empty()&&stack2.empty()){
return true;
}
return false;
}
}
其实就是要在O(1)的时间复杂度内找到栈的最小元素。需要两个栈来实现,一个栈来进行出栈、入栈操作。只需要保证不管如何操作,另一个栈的栈顶元素都是当前栈的最小元素即可。
两个栈stack1、stack2,站的操作都在stack1中:
这样就能保证stack2的栈顶元素总是stack1的最小元素。注意:如果stack1中入栈两个相同的最小元素,都需要对stack2进行入栈。
【代码如下】
class MinStack {
private Stack<Integer> stack1;
private Stack<Integer> stack2;
//构造方法
public MinStack() {
stack1=new Stack<>();
stack2=new Stack<>();
}
//入栈
public void push(int val) {
stack1.push(val);
if(stack2.empty()){
stack2.push(val);
}else{
if(val<=stack2.peek()){
stack2.push(val);
}
}
}
//出栈
public void pop() {
int x=stack1.pop();
if(x==stack2.peek()){
stack2.pop();
}
}
//获取栈顶元素
public int top() {
return stack1.peek();
}
//获取栈的最小元素
public int getMin() {
return stack2.peek();
}
}