leetcode系列-栈与队列

栈与队列的理论基础

1、java中stack 是容器么?

是容器,stack是继承自Vector,底层使用数组存储、用来模拟栈的一个java集合。同时也是线程安全的。

在这里插入图片描述

2、栈里面的元素在内存中是连续分布的么?

这个问题有两个陷阱:

  • 陷阱1:栈是容器适配器,底层容器使用不同的容器,导致栈内数据在内存中是不是连续分布。
  • 陷阱2:缺省情况下,默认底层容器是deque,那么deque的在内存中的数据分布是什么样的呢? 答案是:不连续的,下文也会提到deque。

3、栈的实现

一个是用java本身的集合类型Stack类型;另一个是借用LinkedList来间接实现Stack。

Deque stack=new ArrayDeque();

Deque stack = new LinkedList();

栈方法 等效方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst() isEmpty() //判断是否为空

4、队列的实现

Queue queue = new LinkedList();

队列方法 等效方法
offer(e) offer(e)/offerLast(e) //进队列,将元素加入队列末尾
poll() poll()/pollFirst() //获取队列头的元素并移除
peek() peek()/peekFirst() //获取队列头的元素 isEmpty() //判断是否为空

5、栈在系统中的应用

如果还记得编译原理的话,编译器在 词法分析的过程中处理括号、花括号等这个符号的逻辑,就是使用了栈这种数据结构。

再举个例子,linux系统中,cd这个进入目录的命令我们应该再熟悉不过了。

cd a/b/c/../../

这个命令最后进入a目录,系统是如何知道进入了a目录呢 ,这就是栈的应用。这在leetcode上也是一道题目,编号:71. 简化路径,大家有空可以做一下。

递归的实现是栈:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

所以栈在计算机领域中应用是非常广泛的。

栈经典题目

232-用栈实现队列 Deque push pop

使用栈实现队列的下列操作:

  • push(x) – 将一个元素放入队列的尾部。
  • pop() – 从队列首部移除元素。
  • peek() – 返回队列首部的元素。
  • empty() – 返回队列是否为空。

在这里插入图片描述

/**
 * 队列是一种 先进先出(first in - first out, FIFO)的数据结构
 * 栈是一种 后进先出(last in - first out, LIFO)的数据结构
 *
 * 方法一:双栈
 * 思路
 * 将一个栈当作输入栈,用于压入 push 传入的数据;另一个栈当作输出栈,用于 pop 和 peek 操作。
 * 每次 pop 或 peek 时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。
 *
 */
class MyQueue {
   

    Deque<Integer> inStack;
    Deque<Integer> outStack;

    /** Initialize your data structure here. */
    public MyQueue() {
   

       inStack = new LinkedList<Integer>();
       outStack = new LinkedList<Integer>();

    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
   

        inStack.push(x);

    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
   

        if (outStack.isEmpty()){
   
            in2out();
        }
        return outStack.pop();

    }
    
    /** Get the front element. */
    public int peek() {
   
        if (outStack.isEmpty()){
   
            in2out();
        }
        return outStack.peek();

    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
   
        return inStack.isEmpty() && outStack.isEmpty();
    }

    private void in2out(){
   
        while (!inStack.isEmpty()) {
   
            outStack.push(inStack.pop());
        }
    }

}

复杂度分析

时间复杂度:push 和 empty 为 O(1),pop 和peek 为均摊 O(1)。对于每个元素,至多入栈和出栈各两次,故均摊复杂度为 O(1)。

空间复杂度:O(n)。其中 n 是操作总数。对于有 n 次 push 操作的情况,队列中会有 n 个元素,故空间复杂度为 O(n)

225-用队列实现栈 Queue offer poll

使用队列实现栈的下列操作:

  • push(x) – 元素 x 入栈
  • pop() – 移除栈顶元素
  • top() – 获取栈顶元素
  • empty() – 返回栈是否为空

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时在去弹出元素就是栈的顺序了。

fig1

/**
 *  方法一:两个队列
 *  queue1用于存储栈内的元素,queue2作为入栈操作的辅助队列。
 *
 */
class MyStack {
   
    Queue<Integer> queue1;
    Queue<Integer> queue2;

    /** Initialize your data structure here. */
    public MyStack() {
   
        queue1 = new LinkedList<Integer
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值