栈---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;
    }
}
相关推荐
黑子哥呢?35 分钟前
安装Bash completion解决tab不能补全问题
开发语言·bash
落笔画忧愁e39 分钟前
FastGPT快速将消息发送至飞书
服务器·数据库·飞书
青龙小码农40 分钟前
yum报错:bash: /usr/bin/yum: /usr/bin/python: 坏的解释器:没有那个文件或目录
开发语言·python·bash·liunx
大数据追光猿1 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Σίσυφος19001 小时前
halcon 条形码、二维码识别、opencv识别
前端·数据库
南宫生1 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
小刘|1 小时前
深入理解 SQL 注入漏洞及解决方案
数据库·sql
计算机毕设定制辅导-无忧学长1 小时前
Maven 基础环境搭建与配置(一)
java·maven
彳卸风2 小时前
Unable to parse timestamp value: “20250220135445“, expected format is
开发语言
dorabighead2 小时前
JavaScript 高级程序设计 读书笔记(第三章)
开发语言·javascript·ecmascript