栈---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;
    }
}
相关推荐
风象南29 分钟前
Spring Boot 的 3 种动态 Bean 注入技巧
java·spring boot·后端
移动开发者1号31 分钟前
Kotlinx序列化多平台兼容性详解
android·java·kotlin
东阳马生架构10 小时前
商品中心—6.商品考核系统的技术文档
java
晴空月明10 小时前
Java 内存模型与 Happens-Before 关系深度解析
java
皮皮林55114 小时前
SpringBoot 加载外部 Jar,实现功能按需扩展!
java·spring boot
rocksun14 小时前
认识Embabel:一个使用Java构建AI Agent的框架
java·人工智能
汪子熙14 小时前
HSQLDB 数据库锁获取失败深度解析
数据库·后端
Java中文社群15 小时前
AI实战:一键生成数字人视频!
java·人工智能·后端
王中阳Go16 小时前
从超市收银到航空调度:贪心算法如何破解生活中的最优决策谜题?
java·后端·算法
shepherd11116 小时前
谈谈TransmittableThreadLocal实现原理和在日志收集记录系统上下文实战应用
java·后端·开源