代码随想录算法训练营 DAY 10 | 232.用栈实现队列 225.用队列实现栈

java中的相关方法

Stack stack = new Stack<>();

类:java.util.Stack<> 是一个实现,不是接口

方法:

push():压入元素
pop():弹出栈顶元素,并返回栈顶元素
peek():返回栈顶元素
size():返回长度
empty():栈是否为空
clear():清空

队列

接口:java.util.Queue<>

实现:

java.util.LinkedList<>:双链表
java.util.PriorityQueue<>:优先队列
默认是小根堆,大根堆写法:new PriorityQueue<>(Collections.reverseOrder())

方法:

add():在队尾添加元素
remove():删除并返回队头
isEmpty():是否为空
size():返回长度
peek():返回队头
clear():清空

232.用栈实现队列

题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/description/

视频链接:https://www.bilibili.com/video/BV1nY4y1w7VC/?spm_id_from=333.788&vd_source=80cf8293f27c076730af6c32ceeb2689

讲解链接:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

思路

用两个栈,一个输入栈stackIn,一个输出栈stackOut

  • push很简单,直接入到stackIn就行。
  • empty也很简单,两个栈都为空返回true,否则返回false。
  • pop需要进行判断,如果输出栈不为空直接从输出栈里pop。如果输出栈为空,就把输入栈里的元素全部依次入输出栈。
  • peek同理,注意队头元素应该是最早进来的,也就类似于pop,只是不出栈了而已。

在这里插入图片描述

  • 回忆一下java中栈相关的代码!

java中的栈 java.util.Stack<> 是一个实现,不是接口!!

注意stack.pop()会弹出同时返回元素!

  • 还有一个细节:类似模拟的题目,我们在类里先定义成员变量,在构造方法里再实例化。
class MyQueue {
    Stack<Integer> stackIn;
    Stack<Integer> stackOut;

    public MyQueue() {
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        if(!stackOut.empty()) return stackOut.pop();
        else {
            while(!stackIn.empty()) {
                stackOut.push(stackIn.pop());
            }
            return stackOut.pop();
        }
    }
    
    public int peek() {
        if(!stackOut.empty()) return stackOut.peek();
        while(!stackIn.empty()) {
                stackOut.push(stackIn.pop());
            }
            return stackOut.peek();
    }
    
    public boolean empty() {
        if(stackIn.empty() && stackOut.empty()) return true;
        else return false;
    }
}

225.用队列实现栈

题目链接:https://leetcode.cn/problems/implement-stack-using-queues/description/

视频链接:https://www.bilibili.com/video/BV1Fd4y1K7sm/?spm_id_from=333.788&vd_source=80cf8293f27c076730af6c32ceeb2689

讲解链接:https://programmercarl.com/0225.%E7%94%A8%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

思路

如果用两个队列模拟栈,和232类似,都是pop的时候如果出队列为空,要挪动全部元素。不过这里的第二个队列仅仅是用来备份保存的!

  • 一个队列怎么模拟呢?

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

例如队列里有size个元素,我们就 弹出加入 size-1次,再把最后一个元素弹出来就行。

  • 查看栈顶的话,在移动size-1的基础上,peek()完之后,记得把队头元素也弹出来放进去!要恢复原状!

  • 注意:Queue是接口!实现类有LinkedList或PriorityQueue。

class MyStack {
    Queue<Integer> queue; // 和栈中保持一样元素的队列

    public MyStack() {
        queue = new LinkedList<>();
    }
    
    public void push(int x) {
        queue.add(x);
    }
    
    public int pop() {
        int size = queue.size();
        size--;
        while(size-->0) {
            queue.add(queue.remove());
        }
        return queue.remove();
    }
    
    public int top() {
        int size = queue.size();
        size--;
        while(size-->0) {
            queue.add(queue.remove());
        }
        int top = queue.peek();  //记录下来
        queue.add(queue.remove());  //把队头也弹出加入一次,要恢复原状
        return top;
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }
}

day10总结

  • 比较一下队列和栈相关方法的不同:

    队列:

    add():在队尾添加元素
    remove():删除并返回队头
    isEmpty():是否为空

    栈:

    push():压入元素
    pop():弹出栈顶元素,并返回栈顶元素push():压入元素
    pop():弹出栈顶元素,并返回栈顶元素
    peek():返回栈顶元素

其他求长度size(),求堆头/栈顶peek()和清空clear()都是一样的!

  • 注意在java中,栈是一个实现类。而队列是一个接口,实现类有LinkedList和PriorityQueue
### 关于代码随想录 Day04 的学习资料与解析 #### 一、Day04 主要内容概述 代码随想录 Day04 的主要内容围绕 **二叉树的遍历** 展开,包括前序、中序和后序三种遍历方式。这些遍历可以通过递归实现,也可以通过的方式进行迭代实现[^1]。 #### 二、二叉树的遍历方法详解 ##### 1. 前序遍历(Pre-order Traversal) 前序遍历遵循访问顺序:根节点 -> 左子树 -> 右子树。以下是基于递归的实现: ```python def preorderTraversal(root): result = [] def traversal(node): if not node: return result.append(node.val) # 访问根节点 traversal(node.left) # 遍历左子树 traversal(node.right) # 遍历右子树 traversal(root) return result ``` 对于迭代版本,则可以利用显式的来模拟递归过程: ```python def preorderTraversal_iterative(root): stack, result = [], [] current = root while stack or current: while current: result.append(current.val) # 访问当前节点 stack.append(current) # 将当前节点压入 current = current.left # 转向左子树 current = stack.pop() # 弹出顶元素 current = current.right # 转向右子树 return result ``` ##### 2. 中序遍历(In-order Traversal) 中序遍历遵循访问顺序:左子树 -> 根节点 -> 右子树。递归实现如下: ```python def inorderTraversal(root): result = [] def traversal(node): if not node: return traversal(node.left) # 遍历左子树 result.append(node.val) # 访问根节点 traversal(node.right) # 遍历右子树 traversal(root) return result ``` 迭代版本同样依赖结构: ```python def inorderTraversal_iterative(root): stack, result = [], [] current = root while stack or current: while current: stack.append(current) # 当前节点压入 current = current.left # 转向左子树 current = stack.pop() # 弹出顶元素 result.append(current.val) # 访问当前节点 current = current.right # 转向右子树 return result ``` ##### 3. 后序遍历(Post-order Traversal) 后序遍历遵循访问顺序:左子树 -> 右子树 -> 根节点。递归实现较为直观: ```python def postorderTraversal(root): result = [] def traversal(node): if not node: return traversal(node.left) # 遍历左子树 traversal(node.right) # 遍历右子树 result.append(node.val) # 访问根节点 traversal(root) return result ``` 而迭代版本则稍复杂一些,通常采用双法或标记法完成: ```python def postorderTraversal_iterative(root): if not root: return [] stack, result = [root], [] while stack: current = stack.pop() result.insert(0, current.val) # 插入到结果列表头部 if current.left: stack.append(current.left) # 先压左子树 if current.right: stack.append(current.right) # 再压右子树 return result ``` #### 三、补充知识点 除了上述基本的二叉树遍历外,Day04 还可能涉及其他相关内容,例如卡特兰数的应用场景以及组合问题的基础模板[^2][^4]。如果遇到具体题目,可以根据实际需求调用相应算法工具。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值