【数据结构-Java描述】栈与队列OJ题

括号匹配问题:

OJ链接:括号匹配问题

思路:如果是左边括号就一直入栈,当遇到右括号,就将栈顶元素出栈并与该右括号对比是否为一对,如果不是直接return false;当字符串遍历完成,且此时栈为空,则表示结果为true,return true即可。

代码:

public boolean isValid(String s) {
    Stack<Character> stack=new Stack<>();
      for(int i=0;i<s.length();i++){
          if(s.charAt(i)=='(' || s.charAt(i)=='[' || s.charAt(i)=='{')
        {
                stack.push(s.charAt(i));
        }else{
             if(stack.empty()) return false;
             char tmp=stack.pop();
             if(s.charAt(i)==')' && tmp=='(' || s.charAt(i)=='}' && tmp=='{' || s.charAt(i)==']' && tmp=='[' ) continue;
             else return false;
        }
      }
      if(stack.empty()) return true;
      else return false;
    }

栈的弹出压入序列

 OJ链接:栈的弹出压入序列

思路:定义两个指针,分别从两个序列开头开始遍历,如果两个指针对应的值不同,则左边一直入栈,直到值相同,则栈顶元素出栈,右边指针后移,若相同再出栈,直到不同为止,重复两个过程,直到右序列遍历完成,若此时栈为空,则表示满足条件

代码:

public  boolean IsPopOrder(int[] pushA, int[] popA) {
      Stack<Integer> stack = new Stack<>();
         int i=0;
         int j=0;
        for(;i<pushA.length;i++){
            stack.push(pushA[i]);
            while(!stack.empty() && stack.peek()== popA[j]){
                stack.pop();
                 j++;
            }
        }
        return stack.empty();
    }

逆波兰表达式求值

 OJ链接:.逆波兰表达式求值

思路:准备一个栈,如果是数字,压栈,遇到符号,出栈两个元素,首先出栈的元素放在符号右边,后面出栈的元素放在符号右边,形成一个表达式,计算表达式结果,将值压栈,遍历完成后 栈里只剩下一个元素,该元素即为所求值。

代码:

 public static int evalRPN(String[] tokens) {
        Stack<Integer> stack=new Stack<>();
        for(int i=0;i<tokens.length;i++){
            String s=tokens[i];
            if(!s.equals("*") && !s.equals("+") && !s.equals("-") && !s.equals("/") ){
                int tmp=Integer.parseInt(s);
                stack.push(tmp);
            }else{
                int nums2=stack.pop();
                int nums1=stack.pop();
                switch(s){
                    case "+":
                        stack.push(nums1+nums2);
                        break;
                    case "-":
                        stack.push(nums1-nums2);
                        break;
                    case "*":
                        stack.push(nums1*nums2);
                        break;
                    case "/":
                        stack.push(nums1/nums2);
                        break;
                }
            }
        }
        return stack.pop();
    }

最小栈

 OJ链接:最小栈

思路:准备两个栈,一个栈存放压入的元素,另一个栈存放最小的元素,压栈时,只有当第二个栈为空,或压栈的元素小于第二个栈的栈顶元素时,才往第二个栈里放元素,检索最小元素直接看第二个栈栈顶即可,另外,当出栈时出的元素和第二个栈栈顶元素相同,则要同时出栈,

代码:

 public Stack<Integer> stack1;
    public Stack<Integer> stack2;
    public MinStack() {
         stack1=new Stack();
         stack2=new Stack();
    }
    
    public void push(int val) {
        stack1.push(val);
        if(stack2.empty() || val<=stack2.peek()) stack2.push(val);
    }
    
    public void pop() {
        if(stack1.pop().equals(stack2.peek())) stack2.pop();
    }
    
    public int top() {
        return stack1.peek();
        
    }
    
    public int getMin() {
      return stack2.peek();
    }

用队列实现栈

 OJ链接:用队列实现栈

思路:需要两个队列,压栈时,如果第一个队列为空,则直接在在第一个队列入队,如果第一个队列不为空,在第一个队列入队后,第一个队列保留一个元素,其余元素出队,入队到第二个队列。

需要出栈时,如第一个队列不为空,则直接把第一个队列的元素出队,若第一个队列为空,第二个队列保留一个元素,其余元素出队至第一个队列,再把第二个队列仅剩的元素出队,出队完成后,再把第一个队列全部元素入队回第一队,获取栈顶元素的流程类似,只不过第二个队列仅剩的元素无需出队。

代码:

public Queue<Integer> Queue1= new LinkedList<>();
    public Queue<Integer> Queue2= new LinkedList<>();
    public MyStack() {
       
    }
    
    public void push(int x) {
      Queue1.offer(x);
      while(Queue1.size()>1){
          Queue2.offer(Queue1.poll());
      }


    }
    
    public int pop() {
      if(Queue1.isEmpty()){
          while(Queue2.size()>1){
           Queue1.offer(Queue2.poll());
         }
          int tmp=Queue2.poll();
          while(Queue1.size()>0){
           Queue2.offer(Queue1.poll());
         }
         return tmp;
      }else{
          return Queue1.poll();
      }
    }
    
    public int top() {
    if(Queue1.isEmpty()){
          while(Queue2.size()>1){
           Queue1.offer(Queue2.poll());
         }
          int tmp=Queue2.poll();
          while(Queue1.size()>0){
           Queue2.offer(Queue1.poll());
         }
         Queue2.offer(tmp);
         return tmp;
      }else{
          return Queue1.peek();
      }
    }
    
    public boolean empty() {
    return Queue1.isEmpty() && Queue2.isEmpty();
    }

用栈实现队列

 OJ链接:​​​​​​用栈实现队列

思路:准备两个对,入队操作时,直接入队即可。出队时,将第一个栈中只保留一个元素,其他元素均出栈再压栈至第二个栈,再将该元素出栈即可,获取队顶元素的操作也类似。

代码:

public Stack<Integer> stack1=new Stack<>();
    public Stack<Integer> stack2=new Stack<>();
    public MyQueue() {
     
    }
    
    public void push(int x) {
       stack1.push(x);
    }
    
    public int pop() {
        while(stack1.size()>0){
            stack2.push(stack1.pop());
        }
        int tmp=stack2.pop();
        while(stack2.size()>0){
            stack1.push(stack2.pop());
        }
        return tmp;
      }
    public int peek() {
        while(stack1.size()>0){
            stack2.push(stack1.pop());
        }
        int tmp=stack2.peek();
        while(stack2.size()>0){
            stack1.push(stack2.pop());
        }
        return tmp;

设计循环队列

  OJ链接:设计循环队列

思路:用数组实现,定义两个下标指针,一个指向头,一个指向尾,数组需要空出一个空间,不放满,空出空间作为判断队列满的条件。定义一个size,表示当前存放的元素的个数,存放元素时,在尾指针下标的位置存放,然后尾指针+1后再对数组长度取模,取模后才不会越界,删除元素,把头指针位置的元素弹出,头指针+1后取模,判断队列满的条件:因为空出一个位置不存放元素,所以当尾指针+1取模后是头指针,队列已满,当size==0时,队列为空。

代码:

public int[] list;
     public int usedsize;
     public int front=0;
     public int rear=0;
     public int length=0;
    public MyCircularQueue(int k) {
         this.list=new int[k+1];
         this.length=k+1;
    }

    public boolean enQueue(int value) {
        if(isFull()) return false;
        list[rear]=value;
        rear=(rear+1)%length;
        usedsize++;
        return true;
    }

    public boolean deQueue() {
      if(isEmpty()) return false;
        front=(front+1)%length;
        usedsize--;
        return true;
    }

    public int Front() {
        if(isEmpty()) return -1;
        return list[front];
    }

    public int Rear() {
        if(isEmpty()) return -1;
        if(rear==0) return list[length-1];
        else return list[rear-1];
    }

    public boolean isEmpty() {
     if(usedsize==0) return true;
     else return false;
    }

    public boolean isFull() {
    if((rear+1)%length==front) return true;
    else return false;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值