LeetCode刷题Day10——栈和队列(栈和队列的实现,栈的使用)

简介: 一、用栈实现队列

一、用栈实现队列

题目链接:232.用栈实现队列

/**
 * <pre>
 * 首先我们可以想到的方式就是维护两个栈一个存储,一个作为临时移动
 * 每次插入新的元素时,直接入存储的栈,当出队列时,首先把存储栈的所有元素依次移动到临时栈,移动完后临时栈的栈顶元素就是要出队列的元素
 * 此时将其弹出,随后再把元素依次移动回存储栈
 * 这样每次取出元素需要O(n)的时间复杂度
 * 仔细一想我们会发现元素出队列后其实没有必要再把临时栈的所有元素再返回存储栈,只要有元素出栈就从该栈取出即可,因为顺序都是正确的
 * 也就是维护一个插入栈和一个输出栈,每次输出的时候如果输出栈空就把输入栈的元素移动到输出栈,不空就直接输出输出栈的栈顶元素
 * 这样均摊的时间复杂度就是O(1)
 * </pre>
 *
 * @author <a href="https://github.com/Ken-Chy129">Ken-Chy129</a>
 * @date 2023/1/11 12:18
 */
public class 用栈实现队列232 {
}
class MyQueue {
    Stack<Integer> inStack;
    Stack<Integer> outStack;
    public MyQueue() {
        inStack = new Stack<>();
        outStack = new Stack<>();
    }
    public void push(int x) {
        inStack.push(x);
    }
    public int pop() {
        if (outStack.empty()) {
            while (!inStack.empty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.pop();
    }
    public int peek() {
        if (outStack.empty()) {
            while (!inStack.empty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.peek();
    }
    public boolean empty() {
        return inStack.empty() && outStack.empty();
    }
}

二、用队列实现栈

题目链接:225. 用队列实现栈

/**
 * <pre>
 * 两个队列模拟栈不能和两个栈模拟队列一样实现,因为栈的进出顺序是相反(先入后出)的,所以移动到输出栈后输出就是队列的顺序
 * 而队列的进出顺序是一致(先入先出),所以如果按栈的方法搬移到另一个队列,实质上两个队列顺序都是一样的,没有效果
 * 所以选择将一个队列作为临时队列辅助存储,以保证输入的元素在队列的头部
 * 我们只需要输入前先把队列中的元素移动到另一个队列保存,然后新元素入到原队列后再把临时队列元素重新加回原队列
 * 这样的话插入元素的时间复杂度就是O(n)
 * 
 * 也可以使用一个队列实现,记录下当前元素数量,将新元素入队之后,让队列不断将元素出队再入队,使得前面的元素移动到队列后免去,循环的次数为原本队列的元素数量
 * </pre>
 *
 * @author <a href="https://github.com/Ken-Chy129">Ken-Chy129</a>
 * @date 2023/1/11 13:29
 */
public class 用队列实现栈225 {
}
class MyStack {
    Queue<Integer> queue;
    Queue<Integer> tmpQueue;
    public MyStack() {
        queue = new LinkedList<>();
        tmpQueue = new LinkedList<>();
    }
    public void push(int x) {
        while (!queue.isEmpty()) {
            tmpQueue.add(queue.remove());
        }
        queue.add(x);
        while (!tmpQueue.isEmpty()) {
            queue.add(tmpQueue.remove());
        }
    }
    public int pop() {
        return queue.remove();
    }
    public int top() {
        return queue.element();
    }
    public boolean empty() {
        return queue.isEmpty();
    }
}

三、有效的括号

题目链接:20. 有效的括号

/**
 * <pre>
 * 用栈维护
 * </pre>
 *
 * @author <a href="https://github.com/Ken-Chy129">Ken-Chy129</a>
 * @date 2023/1/11 13:53
 */
public class 有效的括号20 {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        if (s.length() % 2 == 1) { // 奇数一定不满足
            return false;
        }
        for (int i=0; i<s.length(); i++) {
            if (stack.size() > s.length() - i) { // 剩下的括号数小于当前已存在的括号数一定不满足
                return false;
            }
            if (stack.empty()) {
                stack.push(s.charAt(i));
                continue;
            }
            Character peek = stack.peek();
            char c = s.charAt(i);
            if (peek == '(' && c == ')' || peek == '[' && c == ']' || peek == '{' && c == '}') {
                stack.pop();
            } else if (c == ')' || c == ']' || c == '}') { // 当前是右括号且不与上一个左括号匹配,则一定不满足
                return false;
            } else {
                stack.push(c);
            } 
        }
        return stack.empty();
    }
}

四、删除字符串中的所有相邻重复项

题目链接:1047. 删除字符串中的所有相邻重复项

/**
 * <pre>
 * 用StringBuilder模拟栈,以方便最终转换为字符串
 * 也可以采用数组模拟,核心是利用指针指向栈顶元素,维护栈的思想
 * </pre>
 *
 * @author <a href="https://github.com/Ken-Chy129">Ken-Chy129</a>
 * @date 2023/1/11 14:10
 */
public class 删除字符串中的所有相邻重复项1047 {
    public String removeDuplicates(String s) {
        StringBuilder stack = new StringBuilder();
        int top = -1;
        for (int i=0; i<s.length(); i++) {
            if (top == -1) {
                stack.append(s.charAt(i));
                top++;
            } else {
                if (stack.charAt(top) == s.charAt(i)) {
                    stack.deleteCharAt(top--);
                } else {
                    stack.append(s.charAt(i));
                    top++;
                } 
            }
        }
        return stack.toString();
    }
}
相关文章
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
35 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
12 0
|
2月前
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
21 0
|
4月前
|
Python
【Leetcode刷题Python】1467. 两个盒子中球的颜色数相同的概率
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
46 0
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
59 6
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
52 4
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
121 2
|
4月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
66 7