当前位置: 首页 > article >正文

栈---java--黑马

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

定义

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

栈的实现

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

基于链表的实现

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;
            }
        }
    }
}

基于数组的实现

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

方法一
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();
        
    }	
}
方法二
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
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();
	}
}

中缀表达式转后缀表达式

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

使用了两个队列
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();
    }
}
使用单个队列
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;
    }
}

http://www.kler.cn/a/300214.html

相关文章:

  • thinkphp8在使用apidoc时, 4层的接口会有问题 解决办法
  • 开篇:吴恩达《机器学习》课程及免费旁听方法
  • 通过docker overlay2目录名查找容器名和容器ID
  • 【二叉树的深搜】计算布尔二叉树的值 求根节点到叶节点数字之和
  • 产品经理面试题总结2025【其一】
  • leetcode 面试经典 150 题:插入区间
  • Git的Rebase操作,手动merge时主分支的提交记录的保留规则
  • 【Redis】redis5种数据类型(list)
  • vue如何获取一个元素的基本信息
  • 15 章 在微服务中服务众多如何实践他们复杂的依赖关系进行 helm安装
  • Robust Image Denoising through Adversarial Frequency Mixup
  • SPI驱动学习四(通过SPI操作外设模块)
  • QT作业3
  • SprinBoot+Vue宠物店管理系统的设计与实现
  • k8s笔记
  • Android - NDK: 在jni层生成java层对象,并调用java层的方法
  • C++ STL-deque容器入门详解
  • Android简易图片浏览器
  • 【CanMV K230 AI视觉】 人体检测
  • 使用ROS2 控制 Isaac Sim 中的机械臂运动
  • QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]
  • Go-ecc加密解密详解与代码_ecdsa
  • mac安装spark
  • 算法知识点————双指针【删除重复元素】【反转链表】
  • Azure AI Search 中的二进制量化:优化存储和加快搜索速度
  • 简洁直白的github快速入门教程(云主机)