栈的压入,栈的弹出,最小栈,用队列实现栈,设计循环队列

 

栈的压入,栈的弹出 

 

输入两个整数序列,第一个序列表示栈的压入序列,判断第二个序列是否可能是该栈的弹出序列,假设压入栈中的所有数字均不相等,如pushA:1,2,3,4,5是某栈的压入序列,序列popA:4,5,3,2,1是该栈序列对应的一个弹出的一个弹出序列。

结论:栈为空的时候,说明是可能的出栈序列。

1.神魔时候入栈?

每次都入栈

2.神魔时候出栈?

栈不为空并且栈顶元素和k下标相等的时候可以出栈

3.定义i,j,都遍历完说明就是了

    public static boolean IsPopOrder(int[] pushA,int[] popA){
        Stack<Integer> stack=new Stack<>();
        int j=0;

        for (int i = 0; i < pushA.length; i++) {
            stack.push(pushA[i]);
            while(!stack.isEmpty()&&stack.peek()==popA[j]&&j<popA.length) {
                stack.pop();
                j++;
            }
            //在while里面判断的时候,stac弹出的已经是引用类型,这里就发生了自动拆箱
            //但是在牛客网中提交并没有问题
        }
        return stack.isEmpty();

    }

 

最小栈

/****给定stack,和minStack
 * 1.当栈中第一次存放数据时,两个栈中都要存放元素
 * 2.从第二次开始,每次入栈,都要和栈顶元素进行比较,小于的话就入栈
 * 此操作保证了minStack中的栈顶元素时当时的较小值;
 * 3.出栈:每次出栈都要和栈顶元素进行比较,如果和栈顶元素一样,那麽就要两个栈都得出
 *
 * **/
import java.util.Stack;

class MinStack {
    private Stack<Integer> stack ;
    private Stack<Integer> minStack ;
    public MinStack() {
        stack = new Stack<>();
        minStack = new Stack<>();
    }
    
    public void push(int val) {
        stack.push(val);
        //第一次在最小栈当中存储元素
        if(minStack.empty()) {
            minStack.push(val);
        }else {
            if(val <= minStack.peek()) {
                minStack.push(val);
            }
        }
    }
    
    public void pop() {
        //栈为空 则不能进行弹出元素
        if(stack.empty()) {
            return;
        }
        int val = stack.pop();
        if(val == minStack.peek()) {
            minStack.pop();
        }
    }
    //获取栈顶元素 和 最小栈没有关系
    public int top() {
        if(stack.empty()) {
            return -1;
        }
        return stack.peek();
    }

    //获取元素 不是删除元素
    public int getMin() {
        return minStack.peek();
    }
    public static void main(String[] args) {
        MinStack minStack1 = new MinStack();
        minStack1.push(-2);
        minStack1.push(0);
        minStack1.push(1);
        int x1 = minStack1.getMin();
        int x2 = minStack1.top();
        minStack1.pop();
        int x4 = minStack1.getMin();
    }
}

 

用队列实现栈

//栈:push,pop,peek;

//队列:offer,poll,peek

你觉得一个普通的队列能实现这个栈嘛?必然不能!

弄两个队列

1.push元素应该怎末放?

//放入不为空的队列

2.出栈?

将不为空的队列中的n-1个到另一个队列中。剩下的就是要出栈的元素

d81574ebad5f45adb64856f5283dbe27.png 

740dd2936d6b4e11a94985c2767642ee.png 

class MyStack {
    public Queue<Integer> qu1;
    public Queue<Integer> qu2;
    public MyStack() {
        qu1=new LinkedList<>();
        qu2=new LinkedList<>();
    }
    public void push(int x) {
        //只要放到不为空的队列中就行
        if(!qu1.isEmpty()){
            qu1.offer(x);
        }else if(!qu2.isEmpty()){
            qu2.offer(x);
        }else{
            qu1.offer(x);
        }
    }
    public int pop() {
        //两个队列都是空意味着栈是空的
        if(empty()){
            return -1;
        }
        //出不为空的队列
        if(!qu1.isEmpty()){
            //易错
            int currentSize=qu1.size();
            //注意:你的这个不能写死,如果全写在for中是不可以的,因为你的队列每弹出一个元素,大小都在变化
            for(int i=0;i<currentSize-1;i++){
                int x=qu1.poll();
                qu2.offer(x);
            }
            return qu1.poll();
        }
          if(!qu2.isEmpty()){
            int currentSize=qu2.size();
            for(int i=0;i<currentSize-1;i++){
                int x=qu2.poll();
                qu2.offer(x);
            }
            return qu2.poll();
        }
        return -1;
    }
    //peek()方法
    public int top() {
//最后一个在x中存放的就是top元素
          if(empty()){
            return -1;
        }
        //出不为空的队列
        if(!qu1.isEmpty()){
            //易错
            int currentSize=qu1.size();
            //注意:你的这个不能写死,如果全写在for中是不可以的,因为你的队列每弹出一个元素,大小都在变化
            int x=-1;
            for(int i=0;i<currentSize;i++){
                x=qu1.poll();
                qu2.offer(x);
            }
            return x;
        }
          if(!qu2.isEmpty()){
            int currentSize=qu2.size();
            int x=-1;
            for(int i=0;i<currentSize;i++){
                x=qu2.poll();
                qu2.offer(x);
            }
            return x;
        }
        return -1;
    }
    
    public boolean empty() {
        return qu1.isEmpty()&&qu2.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

 设计循环队列

以浪费一个空间判断

class MyCircularQueue {
    private int[] elem;
    private int front;//队头下标
    private int rear;//队尾下标

    public MyCircularQueue(int k) {
        this.elem = new int[k+1];
    }

    //入队
    public boolean enQueue(int value) {
        if(isFull()) {
            return false;
        }
        elem[rear] = value;
        rear = (rear+1) % elem.length;
        return true;
    }

    //出队
    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        front = (front+1) % elem.length;
        return true;
    }

    //得到队头元素
    public int Front() {
        if(isEmpty()) {
            return -1;
        }
        return elem[front];
    }
    //得到队尾元素
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        int index = (rear == 0) ? elem.length-1 : rear-1;
        return elem[index];
    }
    
    public boolean isEmpty() {
        return rear == front;
    }
    
    public boolean isFull() {
        return (rear+1) % elem.length == front;
    }


    // public static void main(String[] args) {
    //     MyCircularQueue myCircularQueue = new MyCircularQueue(3);
    //     System.out.println(myCircularQueue.enQueue(1));
    //     System.out.println(myCircularQueue.enQueue(2));
    //     System.out.println(myCircularQueue.enQueue(3));
    //     System.out.println(myCircularQueue.enQueue(4));
    //     System.out.println(myCircularQueue.Rear());//  2
    //     System.out.println(myCircularQueue.isFull());
    //     System.out.println(myCircularQueue.deQueue());
    //     System.out.println(myCircularQueue.enQueue(4));
    //     System.out.println(myCircularQueue.Rear());
    // }
}

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sqyaa.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值