栈---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;
    }
}
相关推荐
卫生纸不够用20 分钟前
远程链接mysql步骤
数据库·mysql
枫叶_v21 分钟前
【SpringBoot】20 同步调用、异步调用、异步回调
java·spring boot·后端
鸣弦artha28 分钟前
蓝桥杯——杨辉三角
java·算法·蓝桥杯·eclipse
未知陨落35 分钟前
数据结构——二叉搜索树
开发语言·数据结构·c++·二叉搜索树
大波V536 分钟前
设计模式-参考的雷丰阳老师直播课
java·开发语言·设计模式
计算机-秋大田42 分钟前
基于微信小程序的平安驾校预约平台的设计与实现(源码+LW++远程调试+代码讲解等)
java·spring boot·微信小程序·小程序·vue·课程设计
无敌最俊朗@1 小时前
unity3d————接口基础知识点
开发语言·c#
《源码好优多》1 小时前
基于Java Springboot旅游信息推荐系统
java·spring boot·旅游
岁月无声code1 小时前
Spring Boot 牛刀小试 org.springframework.boot:spring-boot-maven-plugin:找不到类错误
java·spring boot·github
夏小花花1 小时前
postgresql 创建序列
数据库·postgresql