栈---java--黑马

大家不用看,直接去Leetcode上刷题

定义

stack 是一种线性数据结构,只能在其一端添加数据和移除数据。习惯来讲,这一端称之为栈顶 ,另一端不能操作数据的称之为栈底

栈的实现

java 复制代码
public interface Stack<E> {
    
    // 向栈的顶端压入元素
    // 压入成功,返回true; 否则返回false
    boolean push(E value);
    
    // 弹出栈顶元素
    // 栈非空弹出栈顶元素,否则返回null
    E pop();
    
    // 获取栈顶元素,不弹出
    // 栈非空弹出栈顶元素,否则返回null
    E peek();
    
    // 判断栈是否为空
    boolean isEmpty();
    
    // 判断栈是否满
    boolean isFull();
}

基于链表的实现

java 复制代码
public class LinkedListStack<E> implements Stack<E>, Iterable<E> {
    
    
    static class Node<E> {
        E val;
        Node<E> next;
        
        public Node(E val) {
            this.val = val;
        }
        
        public Node (E val, Node<E> next) {
            this.val = val;
            this.next = next;
        }
    }
    
    private int capacity;
    private int size;
    private Node<E> head = new Node<>(null, null);
    
    public LinkedListStack(int capacity) {
        this.capacity = capacity;
    }
    
    @Override
    public boolean push(E val) {
        if (isFull()) {
            return false;
        }
        head.next = new Node(val, head.next);
        size++;
        return true;
    }
    
    @Override
    public E pop() {
        if (isEmpty()) {
            return false;
        }
        Node<E> first = head.next;
        head.next = first.next;
        size--;
        return first.val;
    }
    
    @Override 
    public E peek() {
        if (isEmpty()) {
            return false;
        }
        return head.next.val;
    }
    
    @Override
    public boolean isEmpty(){
        return size == 0;
    }
    
    @Override
    public boolean isFull() {
        return size == capacity;
    }
    
    public Iterator<E> iterator {
        return new Iterable<E> {
            Node<E> p = head.next;
            @Override
            public boolean hasNext(){
                p != null;
            }
            
            @Override
            public E next() {
                E val = p.val;
                p = p.next;
                return val;
            }
        }
    }
}

基于数组的实现

java 复制代码
public class ArrayStack<E> implements Stack<E>, Iterable<E> {
    
    private E[] array;
	private int top;		// 栈顶指针
    
    
    public ArrayStack(int capacity) {
        this.array = (E[]) new Object[capacity];
    }
    
    @Override
    public boolean push(E val) {
        if (isFull()) {
            return false;
        }
        array[top++] = val;
        return true;
    }
    
    @Override
    public E pop() {
        if (isEmpty()) {
            return false;
        }
        E value = array[--top];
        return value;
    }
    
    @Override
    public E peek() {
        if (isEmpty()) {
            return false;
        }
        return array[top - 1];
    }
    
    @Override
    public boolean isEmpty() {
        return top == 0;
    }
    
    @Override
    public boolean isFull() {
        return top == array.length;
    }
    
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int p = top;
            @Override
            public boolean hasNext() {
                return p > 0;
            }
            
            @Override
            public E next() {
                E value = array[--top];
                return value;
            }
        }
    }
}

应用

力扣20

方法一
java 复制代码
public class Leetcode20{
    
    public boolean isValid(String s) {
        ArrayStack<Character> stack = new ArrayStack<>(s.length());
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') {
                stack.push(')');
            } else if (c == '[') {
                stack.push(']');
            } else if (c == '{') {
                stack.push('}');
            } else {
                if (!stack.isEmpty() && c == stack.peek()) {
                    stack.pop();
                } else {
                    return false;
                }
            }
        }
        return stack.isEmpty();
        
    }	
}
方法二
java 复制代码
public class Leetcode20{
    
    Deque<Character> stack = new LinkedList<Character>();
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') {
                stack.push(')');
            } else if (c == '[') {
                stack.push(']');
            } else if (c == '{') {
                stack.push('}');
            } else {
                if (!stack.isEmpty() && c == stack.peek()) {
                    stack.pop();
                } else {
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }
}

力扣150题

逆波兰表达式也称之为后缀表达式,即运算符写在后面

  • 从左向右计算

  • 不必考虑运算符优先级,即不用包含括号

    输入:token = ["2", "1", "+", "3", "*"];
    输出: 9
    即:(2 + 1) * 3 = 9

    输入:token = ["4", "13", "5", "/", "+"];
    输出: 6
    即:13 / 5 + 3 = 9

java' 复制代码
public class Leetcode150{
	
	public int evalRPN(String[] tokens) {
		LinkedList<Integer> stack = new LinkedList<>();
		for(String t : tokens) {
			switch (t) {
				case "+" -> {
					Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a + b);
				}
				case "-" -> {
					Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a - b);
				}
				case "*" -> {
					Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a * b);
				}
				case "/" -> {
					Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a / b);
				}
				default -> {  // 数字
					stack.push(Integer.parseInt(t));
				}
			}
		}
		return stack.pop();
	}
}

中缀表达式转后缀表达式

java 复制代码
public class InfixToSuffix {
    
    static int priority(char c) {
        switch (c) {
        	case "*", "/" -> 2;
            case "+", "-" -> 1;
            case "(" -> 0;
                default -> throw new IllegalArgumentException("不合法得运算符," + c);
        }
    }
    
    public String infixToSuffix(String[] exp) {
        LinkedList<Character> stack = new LinkedList<>();
        StringBuilder sb = new StringBuilder(exp.length());
        for(int i = 0; i < exp.length(); i++) {
            char c = exp.charAt(i);
            switch (c) {
                    case "*", "/", "+", "-" -> {
                        if (stack.isEmpty()) {
                            stack.push(c);
                        } else {
                            if (priority(c) > priority(stack.peek())) {
                                stack.push(c);
                            } else {
                                while (stack.isEmpty() && priority(c) <= priority(stack.pop())) {
                                    sb.append(stack.pop());
                                }
                                stack.push(c);
                            }
                        }
                    }
                    case "(" -> {
                        stack.push(c);
                    }
                    case ")" -> {
                        while (!stack.isEmpty() && stack.peek() != "(") {
                            sb.append(stack.pop());
                        }
                        stack.pop();
                    }
                    default -> {
                        sb.append(c);
                    }
            }
        }
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
    } 
}

使用队列实现栈--leetcode225

使用了两个队列
java 复制代码
public class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    public void push(int x) {
        queue2.offer(x);
        while (!queue1.isEmpty()) {
            queue2.offer(queue1.poll());
        }
        Queue<Integer> temp = queue2;
        queue2 = queue1;
        queue1 = temp;
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int peek() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue1.isEmpty();
    }
}
使用单个队列
java 复制代码
public MyStack{
    
    Queue<Integer> queue1;
    public MyStack() {
        queue1 = new LinkedList<>();
    }
    
    public void push(int x) {
        int size = queue1.size();
        queue1.offer(x);
        for(int i = 0; i < size; i++) {
            queue1.offer(queue1.poll());
        }
        
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int top() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue1.size() == 0;
    }
}
相关推荐
C-SDN花园GGbond42 分钟前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
高兴就好(石1 小时前
DB-GPT部署和试用
数据库·gpt
这孩子叫逆2 小时前
6. 什么是MySQL的事务?如何在Java中使用Connection接口管理事务?
数据库·mysql
Karoku0662 小时前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
迷迭所归处2 小时前
C++ —— 关于vector
开发语言·c++·算法
码农郁郁久居人下2 小时前
Redis的配置与优化
数据库·redis·缓存
架构文摘JGWZ2 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
leon6252 小时前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab
拾光师3 小时前
spring获取当前request
java·后端·spring
aPurpleBerry3 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j