💕"
春宵一刻值千金,花有清香月有阴。
"💕
作者:Mylvzi
文章主要内容:leetcode刷题之哈希表的应用(1)
1.栈的概念
栈是一种只允许在一端(栈顶)进行数据操作的数据结构,具有“后进先出”的特性,也叫做Last in First Out

最常见的现实生活中的例子就是压子弹 只能一端压子弹

2.栈的模拟实现
我们想想什么可以实现栈的操作呢?我们知道,栈最大的特性就行只能在一端进行数据操作,使用数组可以更好的模拟栈
数组的末尾就是我的栈顶,操作栈顶就是操作数组的最后一个元素,而数组最后一个元素的添加,删除都很方便!!!

1.使用数组模拟
public class MyStack {
    /**
     * 栈的实现一:用数组实现栈
     */
    private int[] elem;
    private int usedSize;
    private static final int DEFAULTCAPACITY = 10;
    public MyStack() {
        this.elem = new int[DEFAULTCAPACITY];
    }
    public MyStack(int size) {
        this.elem = new int[size];
    }
    public void push(int val) {
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        this.elem[usedSize] = val;
        this.usedSize++;
    }
    private boolean isFull() {
        return this.usedSize == this.elem.length;
/*        if (this.elem.length == this.usedSize) {
            return true;
        }
        return false;*/
    }
    public int pop() {
        if (isEmpty()) {
            throw new StackEmptyException("栈区之内不含有数据,无法删除");
        }
//        this.usedSize--;
//        return this.elem[usedSize];
        int oldVal = this.elem[usedSize-1];
        this.usedSize--;
        return oldVal;
    }
    public int peek() {
        if (isEmpty()) {
            throw new StackEmptyException("栈区之内不含有数据,无法删除");
        }
        return this.elem[usedSize-1];
    }
    public boolean isEmpty() {
        return this.usedSize == 0;
/*        if (this.usedSize == 0) {
            return true;
        }
        return false;*/
    }
}2.使用链表模拟
当然除了使用数组模拟栈,使用链表也可以实现栈的功能(Java中的LinkedList本质上是一个无头双向非循环链表)
class Mystack3 {
    // 使用链表模拟栈
    /**
     * 栈只能在一端进行数据的操作
     * 在这里我们只在链表的last进行数据的操作
     */
    LinkedList<Integer> mystack = new LinkedList<>();
    // push
    public void push(int data) {
        mystack.addLast(data);
    }
    // pop
    public int pop() {
        if(mystack.isEmpty()) {
            return -1;// 抛异常也可以
        }
        return mystack.pollLast();
    }
    public int peek() {
        return mystack.peekLast();
    }
    public static void main(String[] args) {
        Mystack3 mystack3 = new Mystack3();
        mystack3.push(1);
        mystack3.push(2);
        mystack3.push(3);
        System.out.println(mystack3.pop());// 3
        System.out.println(mystack3.peek());// 2
    }
}3.Java中的栈Stack
Java中提供了现成的栈供我们使用


代码演示
// 栈的创建  栈在Java中就是一个类!!!
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        // 使用构造器
        Iterator<Integer> it= stack.iterator();
        while (it.hasNext()) {
            System.out.print(it.next()+" ");// 1 2 3 4
        }
        System.out.println();
        System.out.println("============================");
        // 重写了toString方法  直接传对象 即可打印内容
        System.out.println(stack);// 1 2 3 4
        // pop会删除栈顶元素
        stack.pop();
        System.out.println(stack);// 1 2 3
        // peek  瞄一眼  不会把top删除
        int x = stack.peek();
        System.out.println(x);// 3
    }4.栈的应用场景
1.括号匹配问题
20. 有效的括号 - 力扣(LeetCode) https://leetcode.cn/problems/valid-parentheses/
https://leetcode.cn/problems/valid-parentheses/

分析:

代码实现:
class Solution {
    public static boolean isValid(String s) {
        if(s.length() % 2 != 0) return false;
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            // 获取当前字符
            char ch = s.charAt(i);
            // 左括号
            if(ch == '(' || ch == '{' || ch == '[') {
                stack.push(ch);
            }else {// 右括号
                if(stack.isEmpty()) {
                   return false;
                }else {
                    // 要进行括号匹配
                    char top = stack.peek();
                    if(ch == '}' && top == '{' || ch == ')' && top == '(' ||ch == ']' && top == '[') {
                        stack.pop();
                    }else {
                        return false;
                    }
                }
            }
        }
        return stack.isEmpty();
    }
}也可以使用顺序表实现
class Solution {
    public static boolean isValid(String s) {
        if(s.length() % 2 != 0) return false;
        List<Character> list = new ArrayList<>();
        for (int i = 0; i < s.length(); i++) {
            // 获取当前字符
            char ch = s.charAt(i);
            // 左括号
            if(ch == '(' || ch == '{' || ch == '[') {
                list.add(ch);
            }else {// 右括号
                if(list.isEmpty()) {
                   return false;
                }else {
                    // 要进行括号匹配
                    char top = list.get(list.size()-1);
                    if(ch == '}' && top == '{' || ch == ')' && top == '(' ||ch == ']' && top == '[') {
                        list.remove(list.size()-1);
                    }else {
                        return false;
                    }
                }
            }
        }
        return list.isEmpty();
    }
}2.后缀表达式


代码实现:
class Solution {
    public int evalRPN(String[] tokens) {
        // 遇到数字存放到栈中
        Stack<Integer> stack = new Stack<>();
        // 循环遍历所给字符串
        for(String s : tokens) {
            // 数字
            if(!isOperation(s)) {
                // 是数字就push
                stack.push(Integer.parseInt(s));
            }else {// 运算符
            // 先弹出的作右运算符  后弹出的是左运算符
                int num2 = stack.pop();
                int num1 = stack.pop();
                switch(s) {
                    case "+":
                        stack.push(num1+num2);
                        break;
                    case "-":
                        stack.push(num1-num2);
                        break;
                    case "*":
                        stack.push(num1*num2);
                        break;
                    case "/":
                        stack.push(num1/num2);
                        break;    
                }
            }
        }
        // 遍历完  返回栈的最后一个(唯一一个)元素
        return stack.pop();
    }
    // 判断是否是运算符
    private boolean isOperation(String s) {
        if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
            return true;
        }
        return false;
    }
}3.最小栈
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 https://leetcode.cn/problems/min-stack/submissions/分析思路:
https://leetcode.cn/problems/min-stack/submissions/分析思路:

代码实现:使用两个栈
    class MinStack {
        //思路1 使用两个栈
        private Stack<Integer> stack;
        private Stack<Integer> minstack;// 存放过程中的最小值
        public MinStack() {
            this.stack = new Stack<>();
            this.minstack = new Stack<>();
        }
        
        public void push(int val) {
            if(minstack.isEmpty()) {
                minstack.push(val);
            }else {
                if (val <= minstack.peek()) {
                    minstack.push(val);
            }
            }
            stack.push(val);
        }
        public void pop() {
            if(!stack.isEmpty()) {
                int top = stack.pop();
                if (top == minstack.peek()) {
                    minstack.pop();
            }
            
            }
            
        }
        public int top() {
            if(stack.empty()) {
            return -1;
        }
            return stack.peek();
        }
        public int getMin() {
            if (minstack.isEmpty()) {
                return -1;
            }
            return minstack.peek();
        }
    }思路2:使用链表实现
画图分析

代码实现
 class MinStack {
        // 使用链表实现
        private class Node{
            int val;
            int min;
            Node next = null;
            public Node(int val, int min) {
                this.val = val;
                this.min = min;
            }
        }
        
        private Node head;
        public void push(int x) {
            if(head == null) {
                head = new Node(x,x);
            }else {
                Node newNode = new Node(x,Math.min(x,head.min));
                newNode.next = head;
                head = newNode;
            }
        }
        public void pop() {
            head = head.next;
        }
        public int top() {
            return head.val;
        }
        public int getMin() {
            return head.min;
        }
    }





![2023年中国AI基础设施行业发展趋势分析:AI基础设施将保持高速增长[图]](https://img-blog.csdnimg.cn/img_convert/02a1f6469fb72d3175d63f5ea0255200.png)
















