算法跟练第九弹——栈与队列

跟着代码随想录刷题的第九天。

代码随想录链接:代码随想录

part01 用栈实现队列

题目链接:232.用栈实现队列

代码:

class MyQueue {
    
    Stack<Integer> sIn = new Stack<>();
    Stack<Integer> sOut = new Stack<>();

    public MyQueue() {
        
    }
    
    public void push(int x) {
        sIn.push(x);
    }
    
    public int pop() {
        if(sOut.empty()){
            while(!sIn.empty()){
                sOut.push(sIn.pop());
            }
        }

        int result = sOut.pop();
        return result;
    }
    
    public int peek() {
        if(sOut.empty()){
            while(!sIn.empty()){
                sOut.push(sIn.pop());
            }
        }
        int result = sOut.peek();
        return result;
    }
    
    public boolean empty() {
        if(sIn.empty()&&sOut.empty())
            return true;

        return false;
    }
}

题解:本题的关键在于队列是先进先出,栈是先进后出,要用栈来实现队列的功能就需要用两个栈,一个正常存入数据,另一个存入第一个栈出来的数据,这样就能实现队列的功能。值得注意的是,只有当第二个数组为空时,第一个数组的数值再存入到第二个数组当中

part02 用队列实现栈

题目链接:225. 用队列实现栈

代码:

class MyStack {

    Queue<Integer> q1 = new LinkedList<>();
    Queue<Integer> q2 = new LinkedList<>();

    public MyStack() {
        
    }
    
    public void push(int x) {
        q2.add(x);
        while(!q1.isEmpty())
        {
            q2.add(q1.poll());
        }

        Queue<Integer> tmpq = q1;
        q1 = q2;
        q2 = tmpq;
    }
    
    public int pop() {
        return q1.poll();
    }
    
    public int top() {
        return q1.peek();
    }
    
    public boolean empty() {
        return q1.isEmpty();
    }
}

题解:队列实现栈有一个问题,在于把第一个队列的数值输出到另个队列之后,结果还是先进先出,没有任何改变。所以本题就把push进来的值放到队列2中,再把队列1中的值放到队列2中,这样就实现了后进先出

part03 有效的括号

题目链接:20. 有效的括号

代码:

class Solution {
    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)==']')
            {   if(stack.empty())
                    return false;
                if(stack.peek()==makenew(s.charAt(i))){
                    stack.pop();
                    continue;
                }
                return false;
            }
            stack.push(s.charAt(i));
        }

        if(stack.empty())
            return true;
        else
            return false;
    }
    public char makenew(char a){
        char b= ' ';
        switch(a){
        case ')':
            b =  '(';
            break;
        case'}':
            b =  '{';
            break;
        case']':
            b =  '[';
        }
        return b;
    }

}

题解:本题采用的是来实现。由于所有的括号都是一一对应的输入,所以,当遇到右括号的时候,比较栈顶元素是不是左括号,如果是的话,就弹出,否则就返回false。

part04 删除字符串中的所有相邻重复项

题目链接:1047. 删除字符串中的所有相邻重复项

代码:

class Solution {
    public String removeDuplicates(String s) {
        Stack<Character> stack = new Stack<>();
        for(int i = 0;i<s.length();i++){
            if(!stack.empty()&&s.charAt(i)==stack.peek()){
                stack.pop();
                continue;
            }
            stack.push(s.charAt(i));
        }
        StringBuilder a = new StringBuilder();
        while(!stack.empty())
            a.append(stack.pop());
        a.reverse();

        return new String(a);

    }
}

题解:本题和上题解题思路基本一致,用来求解。当遇到和当前字符相同的,就出栈,反之就进栈,继续比较。

归纳

参考来源:https://blog.youkuaiyun.com/2201_75437633/article/details/135733411

定义栈的方法

1、数组

public class ArrayStack {
    private int[] stack;
    private int top;
 
    public ArrayStack(int capacity) {
        stack = new int[capacity];
        top = -1;
    }
 
    public void push(int item) {
        if (top == stack.length - 1) {
            throw new IllegalStateException("Stack is full");
        }
        stack[++top] = item;
    }
 
    public int pop() {
        if (isEmpty()) {
            throw new IllegalStateException("Stack is empty");
        }
        return stack[top--];
    }
 
    public int peek() {
        if (isEmpty()) {
            throw new IllegalStateException("Stack is empty");
        }
        return stack[top];
    }
 
    public boolean isEmpty() {
        return top == -1;
    }
}

2、链表

public class LinkedListStack {
    private Node top;
 
    private class Node {
        int data;
        Node next;
 
        public Node(int data) {
            this.data = data;
            this.next = null;
        }
    }
 
    public LinkedListStack() {
        top = null;
    }
 
    public void push(int item) {
        Node newNode = new Node(item);
        if (isEmpty()) {
            top = newNode;
        } else {
            newNode.next = top;
            top = newNode;
        }
    }
 
    public int pop() {
        if (isEmpty()) {
            throw new IllegalStateException("Stack is empty");
        }
        int item = top.data;
        top = top.next;
        return item;
    }
 
    public int peek() {
        if (isEmpty()) {
            throw new IllegalStateException("Stack is empty");
        }
        return top.data;
    }
 
    public boolean isEmpty() {
        return top == null;
    }
}

3、栈,可以直接调用下面的函数

Stack<Object> stack = new Stack<>();

栈常用的函数:

入栈:push()
出栈:pop()//会返回栈顶元素
获取栈顶元素:peek()
判断栈是否为空:empty()
查找元素在栈中的位置,由栈底到栈顶:serch(Object o)
对当前栈进行清空:clear()

队列

参考来源:https://blog.youkuaiyun.com/2201_75437633/article/details/135823215

定义队列的三种方法

  1. LinkedList是Java中常用的双向链表实现,它同时实现了List接口和Queue接口,因此可以被用作队列来进行元素的添加和移除操作。
  • Queue queue = new LinkedList<>();
  1. ArrayDeque是一种基于数组的双端队列实现,它同样实现了Queue接口,并且在尾部添加和移除元素的操作具有较低的时间复杂度。
  • Queue queue = new ArrayDeque<>();
  1. PriorityQueue是一个基于优先级堆的无界优先级队列实现,它可以确保每次出队的元素都是队列中优先级最高的元素。
  • Queue queue = new PriorityQueue<>();

优先级队列的例子:

Queue<Integer> queue = new PriorityQueue<>();
queue.offer(5); // 入队
queue.offer(3);
int element = queue.poll(); // 出队
System.out.println(element); // 输出:3

队列常用的函数:

入队列:add()或者offer()
出队列:remove()或者poll()//结果返回栈顶元素
获取队列头部的元素:element()peek()
检查队列是否为空:isEmpty()
清空队列中的所有元素:clear()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值